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::Translation

i18n_scope, t

Methods included from Util::Escape

escape, maybe_escape, maybe_unescape, unescape

Constructor Details

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

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 = new_index_hash
  yield self if block_given?
end

Instance Attribute Details

#bucketBucket

Returns 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

#conflict=(value) ⇒ Object (writeonly)

Sets the attribute conflict

Parameters:

  • value

    the value to set the attribute conflict to.



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

def conflict=(value)
  @conflict = value
end

#content_typeString

Returns 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

#etagString

Returns 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

#indexesHash<Set>

Returns 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

#keyString

Returns 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

#last_modifiedTime

Returns 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

Returns 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

#metaHash

Returns 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

#prevent_stale_writesBoolean

Returns 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

#siblingsArray<RObject>, Array<self>

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



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

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

#vclockString Also known as: vector_clock

Returns 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

.load_from_mapreduce(client, response) ⇒ Array<RObject>

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

.on_conflict {|robject| ... } ⇒ Object

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

.on_conflict_hooksArray<Proc>

Returns 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

#attempt_conflict_resolutionRObject

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

#conflict?true, false

Returns Whether this object has conflicting sibling objects (divergent vclocks).

Returns:

  • (true, false)

    Whether this object has conflicting sibling objects (divergent vclocks)



228
229
230
# File 'lib/riak/robject.rb', line 228

def conflict?
  @conflict.present?
end

#dataObject

Returns 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



140
141
142
143
144
145
146
147
# File 'lib/riak/robject.rb', line 140

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

#data=(new_data) ⇒ Object

Returns 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



151
152
153
154
155
156
157
158
# File 'lib/riak/robject.rb', line 151

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

#delete(options = {}) ⇒ Object

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

See Also:



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

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

#deserialize(body) ⇒ Object

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



252
253
254
# File 'lib/riak/robject.rb', line 252

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

#inspectString

Returns A representation suitable for IRB and debugging output.

Returns:

  • (String)

    A representation suitable for IRB and debugging output



257
258
259
260
261
262
263
264
# File 'lib/riak/robject.rb', line 257

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

#load_from_mapreduce(response) ⇒ RObject

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:



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/riak/robject.rb', line 122

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

#raw_dataString

Returns raw data stored in riak for this object’s key.

Returns:

  • (String)

    raw data stored in riak for this object’s key



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

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

#raw_data=(new_raw_data) ⇒ String

Returns 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



171
172
173
174
# File 'lib/riak/robject.rb', line 171

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

#reload(options = {}) ⇒ Riak::RObject 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:



197
198
199
200
201
202
# File 'lib/riak/robject.rb', line 197

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

#serialize(payload) ⇒ Object

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



241
242
243
# File 'lib/riak/robject.rb', line 241

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

#store(options = {}) ⇒ Riak::RObject

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



184
185
186
187
188
# File 'lib/riak/robject.rb', line 184

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



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

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

#walk(*params) ⇒ Object

Walks links from this object to other objects in Riak.

Parameters:



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

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