Class: Riak::RObject

Inherits:
Object show all
Extended by:
Util::Escape, Util::Translation
Includes:
Util::Escape, Util::Translation
Defined in:
lib/riak/robject.rb

Overview

Represents the data and metadata stored in a bucket/key pair in the Riak database, the base unit of data manipulation.

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Util::Escape

escape, maybe_escape, maybe_unescape, unescape

Methods included from Util::Translation

i18n_scope, t

Constructor Details

- (RObject) initialize(bucket, key = nil) { ... }

Create a new object manually

Parameters:

  • bucket (Bucket)

    the bucket in which the object exists

  • key (String) (defaults to: nil)

    the key at which the object resides. If nil, a key will be assigned when the object is saved.

Yields:

  • self the new RObject

See Also:



103
104
105
106
107
108
# File 'lib/riak/robject.rb', line 103

def initialize(bucket, key=nil)
  @bucket, @key = bucket, key
  @links, @meta = Set.new, {}
  @indexes = Hash.new {|h,k| h[k] = Set.new }
  yield self if block_given?
end

Instance Attribute Details

- (Bucket) bucket

The bucket in which this object is contained

Returns:

  • (Bucket)

    the bucket in which this object is contained



21
22
23
# File 'lib/riak/robject.rb', line 21

def bucket
  @bucket
end

- (Object) conflict=(value) (writeonly)

Sets the attribute conflict

Parameters:

  • value

    the value to set the attribute conflict to.



209
210
211
# File 'lib/riak/robject.rb', line 209

def conflict=(value)
  @conflict = value
end

- (String) content_type

The MIME content type of the object

Returns:

  • (String)

    the MIME content type of the object



27
28
29
# File 'lib/riak/robject.rb', line 27

def content_type
  @content_type
end

- (String) etag

The ETag header from the most recent HTTP response, useful for caching and reloading

Returns:

  • (String)

    the ETag header from the most recent HTTP response, useful for caching and reloading



36
37
38
# File 'lib/riak/robject.rb', line 36

def etag
  @etag
end

- (Hash<Set>) indexes

A hash of secondary indexes, where the key is the index name and the value is a Set of index entries for that index

Returns:

  • (Hash<Set>)

    a hash of secondary indexes, where the key is the index name and the value is a Set of index entries for that index



47
48
49
# File 'lib/riak/robject.rb', line 47

def indexes
  @indexes
end

- (String) key

The key of this object within its bucket

Returns:

  • (String)

    the key of this object within its bucket



24
25
26
# File 'lib/riak/robject.rb', line 24

def key
  @key
end

- (Time) last_modified

The Last-Modified header from the most recent HTTP response, useful for caching and reloading

Returns:

  • (Time)

    the Last-Modified header from the most recent HTTP response, useful for caching and reloading



39
40
41
# File 'lib/riak/robject.rb', line 39

def last_modified
  @last_modified
end

A Set of Link objects for relationships between this object and other resources

Returns:

  • (Set<Link>)

    a Set of Link objects for relationships between this object and other resources



33
34
35
# File 'lib/riak/robject.rb', line 33

def links
  @links
end

- (Hash) meta

A hash of any X-Riak-Meta-* headers that were in the HTTP response, keyed on the trailing portion

Returns:

  • (Hash)

    a hash of any X-Riak-Meta-* headers that were in the HTTP response, keyed on the trailing portion



42
43
44
# File 'lib/riak/robject.rb', line 42

def meta
  @meta
end

- (Boolean) prevent_stale_writes

Whether to attempt to prevent stale writes using conditional PUT semantics, If-None-Match: * or If-Match: #etag

Returns:

  • (Boolean)

    whether to attempt to prevent stale writes using conditional PUT semantics, If-None-Match: * or If-Match: #etag

See Also:



51
52
53
# File 'lib/riak/robject.rb', line 51

def prevent_stale_writes
  @prevent_stale_writes
end

- (Array<RObject>, Array<self>) siblings

Returns sibling objects when in conflict. in conflict

Returns:

  • (Array<RObject>)

    an array of conflicting sibling objects for this key

  • (Array<self>)

    a single-element array containing object when not



215
216
217
218
# File 'lib/riak/robject.rb', line 215

def siblings
  return [self] unless conflict?
  @siblings
end

- (String) vclock Also known as: vector_clock

The Riak vector clock for the object

Returns:

  • (String)

    the Riak vector clock for the object



30
31
32
# File 'lib/riak/robject.rb', line 30

def vclock
  @vclock
end

Class Method Details

+ (Array<RObject>) load_from_mapreduce(client, response)

Loads a list of RObjects that were emitted from a MapReduce query.

Parameters:

  • client (Client)

    A Riak::Client with which the results will be associated

  • response (Array<Hash>)

    A list of results a MapReduce job. Each entry should contain these keys: bucket, key, vclock, values

Returns:



92
93
94
95
96
# File 'lib/riak/robject.rb', line 92

def self.load_from_mapreduce(client, response)
  response.map do |item|
    RObject.new(client[unescape(item['bucket'])], unescape(item['key'])).load_from_mapreduce(item)
  end
end

+ (Object) on_conflict {|robject| ... }

Note:

Ripple registers its own document-level conflict handler, so if you're using ripple, you will probably want to use that instead.

Defines a callback to be invoked when there is conflict.

Yields:

  • The conflict callback.

Yield Parameters:

  • robject (RObject)

    The conflicted RObject

Yield Returns:

  • (RObject, nil)

    Either the resolved RObject or nil if your callback cannot resolve it. The next registered callback will be given the chance to resolve it.



63
64
65
# File 'lib/riak/robject.rb', line 63

def self.on_conflict(&conflict_hook)
  on_conflict_hooks << conflict_hook
end

+ (Array<Proc>) on_conflict_hooks

The list of registered conflict callbacks.

Returns:

  • (Array<Proc>)

    the list of registered conflict callbacks.



68
69
70
# File 'lib/riak/robject.rb', line 68

def self.on_conflict_hooks
  @on_conflict_hooks ||= []
end

Instance Method Details

- (RObject) attempt_conflict_resolution

Note:

There is no guarantee the returned RObject will have been resolved

Attempts to resolve conflict using the registered conflict callbacks.

Returns:



76
77
78
79
80
81
82
83
84
85
# File 'lib/riak/robject.rb', line 76

def attempt_conflict_resolution
  return self unless conflict?

  self.class.on_conflict_hooks.each do |hook|
    result = hook.call(self)
    return result if result.is_a?(RObject)
  end

  self
end

- (true, false) conflict?

Whether this object has conflicting sibling objects (divergent vclocks)

Returns:

  • (true, false)

    Whether this object has conflicting sibling objects (divergent vclocks)



221
222
223
# File 'lib/riak/robject.rb', line 221

def conflict?
  @conflict.present?
end

- (Object) data

The unmarshaled form of #raw_data stored in riak at this object's key

Returns:

  • (Object)

    the unmarshaled form of #raw_data stored in riak at this object's key



133
134
135
136
137
138
139
140
# File 'lib/riak/robject.rb', line 133

def data
  if @raw_data && !@data
    raw = @raw_data.respond_to?(:read) ? @raw_data.read : @raw_data
    @data = deserialize(raw)
    @raw_data = nil
  end
  @data
end

- (Object) data=(new_data)

The object stored

Parameters:

  • unmarshaled (Object)

    form of the data to be stored in riak. Object will be serialized using #serialize if a known content_type is used. Setting this overrides values stored with #raw_data=

Returns:

  • (Object)

    the object stored



144
145
146
147
148
149
150
151
# File 'lib/riak/robject.rb', line 144

def data=(new_data)
  if new_data.respond_to?(:read)
    raise ArgumentError.new(t("invalid_io_object"))
  end

  @raw_data = nil
  @data = new_data
end

- (Object) delete(options = {})

Delete the object from Riak and freeze this instance. Will work whether or not the object actually exists in the Riak database.

See Also:



202
203
204
205
206
207
# File 'lib/riak/robject.rb', line 202

def delete(options={})
  return if key.blank?
  options[:vclock] = vclock if vclock
  @bucket.delete(key, options)
  freeze
end

- (Object) deserialize(body)

Deserializes the internal object data from a Riak response. Differs based on the content-type. This method is called internally when loading the object. Automatically deserialized formats:

  • JSON (application/json)

  • YAML (text/yaml)

  • Marshal (application/x-ruby-marshal)

Parameters:

  • body (String)

    the serialized response body



245
246
247
# File 'lib/riak/robject.rb', line 245

def deserialize(body)
  Serializers.deserialize(@content_type, body)
end

- (String) inspect

A representation suitable for IRB and debugging output

Returns:

  • (String)

    A representation suitable for IRB and debugging output



250
251
252
253
254
255
256
257
# File 'lib/riak/robject.rb', line 250

def inspect
  body = if @data || Serializers[content_type]
           data.inspect
         else
           @raw_data && "(#{@raw_data.size} bytes)"
         end
  "#<#{self.class.name} {#{bucket.name}#{"," + @key if @key}} [#{@content_type}]:#{body}>"
end

- (RObject) load_from_mapreduce(response)

Load object data from a map/reduce response item. This method is used by RObject::load_from_mapreduce to instantiate the necessary objects.

Parameters:

Returns:



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/riak/robject.rb', line 115

def load_from_mapreduce(response)
  self.vclock = response['vclock']
  if response['values'].size == 1
    value = response['values'].first
    load_map_reduce_value(value)
  else
    @conflict = true
    @siblings = response['values'].map do |v|
      RObject.new(self.bucket, self.key) do |robj|
        robj.vclock = self.vclock
        robj.load_map_reduce_value(v)
      end
    end
  end
  self
end

- (String) raw_data

Raw data stored in riak for this object's key

Returns:

  • (String)

    raw data stored in riak for this object's key



154
155
156
157
158
159
160
# File 'lib/riak/robject.rb', line 154

def raw_data
  if @data && !@raw_data
    @raw_data = serialize(@data)
    @data = nil
  end
  @raw_data
end

- (String) raw_data=(new_raw_data)

The data stored

Parameters:

  • the (String, IO-like)

    raw data to be stored in riak at this key, will not be marshaled or manipulated prior to storage. Overrides any data stored by #data=

Returns:

  • (String)

    the data stored



164
165
166
167
# File 'lib/riak/robject.rb', line 164

def raw_data=(new_raw_data)
  @data = nil
  @raw_data = new_raw_data
end

- (Riak::RObject) reload(options = {}) Also known as: fetch

Reload the object from Riak. Will use conditional GETs when possible.

Parameters:

  • options (Hash) (defaults to: {})

    query parameters

Options Hash (options):

  • :r (Fixnum)

    the "r" parameter (Read quorum)

  • :force (Boolean)

    will force a reload request if the vclock is not present, useful for reloading the object after a store (not passed in the query params)

Returns:



190
191
192
193
194
195
# File 'lib/riak/robject.rb', line 190

def reload(options={})
  force = options.delete(:force)
  return self unless @key && (@vclock || force)
  self.etag = self.last_modified = nil if force
  bucket.client.reload_object(self, options)
end

- (Object) serialize(payload)

Serializes the internal object data for sending to Riak. Differs based on the content-type. This method is called internally when storing the object. Automatically serialized formats:

  • JSON (application/json)

  • YAML (text/yaml)

  • Marshal (application/x-ruby-marshal)

When given an IO-like object (e.g. File), no serialization will be done.

Parameters:

  • payload (Object)

    the data to serialize



234
235
236
# File 'lib/riak/robject.rb', line 234

def serialize(payload)
  Serializers.serialize(@content_type, payload)
end

- (Riak::RObject) store(options = {})

Store the object in Riak

Parameters:

  • options (Hash) (defaults to: {})

    query parameters

Options Hash (options):

  • :r (Fixnum)

    the "r" parameter (Read quorum for the implicit read performed when validating the store operation)

  • :w (Fixnum)

    the "w" parameter (Write quorum)

  • :dw (Fixnum)

    the "dw" parameter (Durable-write quorum)

  • :returnbody (Boolean) — default: true

    whether to return the result of a successful write in the body of the response. Set to false for fire-and-forget updates, set to true to immediately have access to the object's stored representation.

Returns:

Raises:

  • (ArgumentError)

    if the content_type is not defined



177
178
179
180
181
# File 'lib/riak/robject.rb', line 177

def store(options={})
  raise ArgumentError, t("content_type_undefined") unless @content_type.present?
  @bucket.client.store_object(self, options)
  self
end

Converts the object to a link suitable for linking other objects to it

Parameters:

  • tag (String)

    the tag to apply to the link



269
270
271
# File 'lib/riak/robject.rb', line 269

def to_link(tag)
  Link.new(@bucket.name, @key, tag)
end

- (Object) url

Generates a URL representing the object according to the client, bucket and key. If the key is blank, the bucket URL will be returned (where the object will be submitted to when stored).



276
277
278
279
280
# File 'lib/riak/robject.rb', line 276

def url
  segments = [ @bucket.client.http_paths[:prefix], escape(@bucket.name)]
  segments << escape(@key) if @key
  @bucket.client.http.path(*segments).to_s
end

- (Object) walk(*params)

Walks links from this object to other objects in Riak.

Parameters:



261
262
263
264
# File 'lib/riak/robject.rb', line 261

def walk(*params)
  specs = WalkSpec.normalize(*params)
  @bucket.client.link_walk(self, specs)
end