Class: Riak::RObject

Inherits:
Object show all
Extended by:
Forwardable, 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:



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/riak/robject.rb', line 102

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

Instance Attribute Details

#bucketBucket

Returns the bucket in which this object is contained.

Returns:

  • (Bucket)

    the bucket in which this object is contained



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

def bucket
  @bucket
end

#keyString

Returns the key of this object within its bucket.

Returns:

  • (String)

    the key of this object within its bucket



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

def key
  @key
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:



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

def prevent_stale_writes
  @prevent_stale_writes
end

#siblingsArray<RContent>

Returns sibling values. If the object is not in conflict, then only one value will be present in the array.

Returns:

  • (Array<RContent>)

    an array of conflicting sibling values for this key, possibly containing only one



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

def siblings
  @siblings
end

#vclockString Also known as: causal_context, vector_clock

Returns the Riak causal context/vector clock for the object.

Returns:

  • (String)

    the Riak causal context/vector clock for the object



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

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:



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

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.



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

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.



55
56
57
# File 'lib/riak/robject.rb', line 55

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:



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

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)



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

def conflict?
  @siblings.size > 1
end

#contentRContent

Returns the solitary sibling when not in conflict.

Returns:

  • (RContent)

    the sole value/sibling on this object

Raises:

  • (Conflict)

    when multiple siblings are present



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

def content
  raise Conflict, self if conflict?
  raise Tombstone, self if tombstone?
  @siblings.first
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:



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

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

#inspectString

Returns A representation suitable for IRB and debugging output.

Returns:

  • (String)

    A representation suitable for IRB and debugging output



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

def inspect
  body = @siblings.map {|s| s.inspect }.join(", ")
  "#<#{self.class.name} {#{bucket.name}#{"," + @key if @key}} [#{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:



120
121
122
123
124
125
126
127
128
# File 'lib/riak/robject.rb', line 120

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 = {}) ⇒ Array<PreflistItem>

Retrieves a preflist for this RObject; useful for figuring out where in the cluster it is stored.

Returns:



231
232
233
# File 'lib/riak/robject.rb', line 231

def preflist(options = {})
  bucket.get_preflist key, options
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:



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

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

#reviveRiak::RObject

Will “revive” a tombstone object by giving it a new content. If the object is not a tombstone, will just return self.

Returns:



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

def revive
  @siblings = [ RContent.new(self) ] if tombstone?
  self
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

  • (Conflict)

    if the object has siblings



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

def store(options = {})
  fail Conflict, self if conflict?
  fail Tombstone, self if tombstone?
  raise ArgumentError, t('content_type_undefined') unless content_type.present?
  raise ArgumentError, t('zero_length_key') if key == ''
  # NB: key can be nil to indicate that Riak should generate one
  unless key.nil? || key.is_a?(String)
    raise ArgumentError, t('string_type', :string => key)
  end
  @bucket.client.store_object(self, default(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



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

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

#tombstone?true, false

Returns Whether this object is a Riak tombstone (has no RContents, but contains a vclock).

Returns:

  • (true, false)

    Whether this object is a Riak tombstone (has no RContents, but contains a vclock)



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

def tombstone?
  @siblings.empty? && !@vclock.nil?
end