class Riak::RObject

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

Attributes

bucket[RW]

@return [Bucket] the bucket in which this object is contained

causal_context[RW]

@return [String] the Riak causal context/vector clock for the object

causal_context=[RW]

@return [String] the Riak causal context/vector clock for the object

key[RW]

@return [String] the key of this object within its bucket

prevent_stale_writes[RW]

@return [Boolean] whether to attempt to prevent stale writes using

conditional PUT semantics, If-None-Match: * or If-Match: etag

@see wiki.basho.com/display/RIAK/REST+API#RESTAPI-Storeaneworexistingobjectwithakey Riak Rest API Docs

siblings[RW]

Returns sibling values. If the object is not in conflict, then only one value will be present in the array. @return [Array<RContent>] an array of conflicting sibling values

for this key, possibly containing only one
vclock[RW]

@return [String] the Riak causal context/vector clock for the object

vector_clock[RW]

@return [String] the Riak causal context/vector clock for the object

vector_clock=[RW]

@return [String] the Riak causal context/vector clock for the object

Public Class Methods

load_from_mapreduce(client, response) click to toggle source

Loads a list of RObjects that were emitted from a MapReduce query. @param [Client] client A Riak::Client with which the results will be associated @param [Array<Hash>] response A list of results a MapReduce job. Each entry should contain these keys: bucket, key, vclock, values @return [Array<RObject>] An array of RObject instances

# File lib/riak/robject.rb, line 88
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
new(bucket, key = nil) { |self| ... } click to toggle source

Create a new object manually @param [Bucket] bucket the bucket in which the object exists @param [String] key the key at which the object resides. If nil, a key will be assigned when the object is saved. @yield self the new RObject @see Bucket#get

# File lib/riak/robject.rb, line 99
def initialize(bucket, key = nil)
  @bucket, @key = bucket, key

  # fix a require-loop
  require 'riak/bucket_typed/bucket'

  if @bucket.is_a? BucketTyped::Bucket
    @type = @bucket.type.name
  end
  @siblings = [ RContent.new(self) ]
  yield self if block_given?
end
on_conflict(&conflict_hook) click to toggle source

Defines a callback to be invoked when there is conflict.

@yield The conflict callback. @yieldparam [RObject] robject The conflicted RObject @yieldreturn [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.

@note Ripple registers its own document-level conflict handler, so if you’re

using ripple, you will probably want to use that instead.
# File lib/riak/robject.rb, line 49
def self.on_conflict(&conflict_hook)
  on_conflict_hooks << conflict_hook
end
on_conflict_hooks() click to toggle source

@return [Array<Proc>] the list of registered conflict callbacks.

# File lib/riak/robject.rb, line 54
def self.on_conflict_hooks
  @on_conflict_hooks ||= []
end

Public Instance Methods

attempt_conflict_resolution() click to toggle source

Attempts to resolve conflict using the registered conflict callbacks.

@return [RObject] the RObject @note There is no guarantee the returned RObject will have been resolved

# File lib/riak/robject.rb, line 72
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?() click to toggle source

@return [true,false] Whether this object has conflicting sibling objects (divergent vclocks)

# File lib/riak/robject.rb, line 189
def conflict?
  @siblings.size != 1
end
content() click to toggle source

Returns the solitary sibling when not in conflict. @return [RContent] the sole value/sibling on this object @raise [Conflict] when multiple siblings are present

# File lib/riak/robject.rb, line 183
def content
  raise Conflict, self if conflict?
  @siblings.first
end
delete(options = {}) click to toggle source

Delete the object from Riak and freeze this instance. Will work whether or not the object actually exists in the Riak database. @see Bucket#delete

# File lib/riak/robject.rb, line 167
def delete(options = {})
  return if key.blank?
  options[:vclock] = vclock if vclock
  @bucket.delete(key, default(options))
  freeze
end
fetch(options = {})
Alias for: reload
inspect() click to toggle source

@return [String] A representation suitable for IRB and debugging output

# File lib/riak/robject.rb, line 194
def inspect
  body = @siblings.map {|s| s.inspect }.join(", ")
  "#<#{self.class.name} {#{bucket.name}#{"," + @key if @key}} [#{body}]>"
end
load_from_mapreduce(response) click to toggle source

Load object data from a map/reduce response item. This method is used by RObject::load_from_mapreduce to instantiate the necessary objects. @param [Hash] response a response from {Riak::MapReduce} @return [RObject] self

# File lib/riak/robject.rb, line 117
def load_from_mapreduce(response)
  self.vclock = response['vclock']
  @siblings = response['values'].map do |v|
    RContent.new(self) do |rcontent|
      rcontent.load_map_reduce_value(v)
    end
  end
  self
end
preflist(options = {}) click to toggle source

Retrieves a preflist for this RObject; useful for figuring out where in the cluster it is stored. @return [Array<PreflistItem>] an array of preflist entries

# File lib/riak/robject.rb, line 209
def preflist(options = {})
  bucket.get_preflist key, options
end
reload(options = {}) click to toggle source

Reload the object from Riak. Will use conditional GETs when possible. @param [Hash] options query parameters @option options [Fixnum] :r the “r” parameter (Read quorum) @option options [Boolean] :force 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)

@return [Riak::RObject] self

# File lib/riak/robject.rb, line 155
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, default(options))
end
Also aliased as: fetch
store(options = {}) click to toggle source

Store the object in Riak @param [Hash] options query parameters @option options [Fixnum] :r the “r” parameter (Read quorum for the

implicit read performed when validating the store operation)

@option options [Fixnum] :w the “w” parameter (Write quorum) @option options [Fixnum] :dw the “dw” parameter (Durable-write quorum) @option options [Boolean] :returnbody (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.

@return [Riak::RObject] self @raise [ArgumentError] if the content_type is not defined @raise [Conflict] if the object has siblings

# File lib/riak/robject.rb, line 140
def store(options = {})
  fail Conflict, self if conflict?
  fail ArgumentError, t('content_type_undefined') unless content_type.present?
  fail ArgumentError, t('zero_length_key') if key == ''
  @bucket.client.store_object(self, default(options))
  self
end

Private Instance Methods

default(options) click to toggle source
# File lib/riak/robject.rb, line 215
def default(options)
  return options unless options.is_a? Hash
  return options unless @type

  {type: @type}.merge options
end