Class: Blodsband::Riak::Bucket

Inherits:
Object
  • Object
show all
Defined in:
lib/blodsband/riak/bucket.rb

Overview

Encapsulates functionality of Riak buckets.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, name, options = {}) ⇒ Bucket

Parameters:

  • url (::URI)

    a url pointing to the HTML port of a Riak node.

  • name (String)

    the name of the bucket.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :client_id
    String

    client_id to use when communicating with Riak. Will default to a random 256 bit string.

    :unique
    true, false

    if this bucket should always default to :unique => true when doing #get. Will default to false.



29
30
31
32
33
34
# File 'lib/blodsband/riak/bucket.rb', line 29

def initialize(url, name, options = {})
  @url = url
  @name = name
  @defaults = options.merge(:client_id => rand(1 << 256).to_s(36))
  raise "Unknown options to #{self.class}#initialize: #{options}" unless options.empty?
end

Instance Attribute Details

#defaultsObject (readonly)

Hash<Symbol, Object>

The default options for this Blodsband::Riak::Bucket



18
19
20
# File 'lib/blodsband/riak/bucket.rb', line 18

def defaults
  @defaults
end

#nameObject (readonly)

String

The name of the Riak bucket this Blodsband::Riak::Bucket refers to.



14
15
16
# File 'lib/blodsband/riak/bucket.rb', line 14

def name
  @name
end

Instance Method Details

#[](key) ⇒ Blodsband::Riak::Response

Fetch a value from Riak.

Parameters:

  • key (String)

    the key for the value.

Returns:

  • (Blodsband::Riak::Response)

    the response from Riak for the resulting HTTP request (which will also be ie a String or a Hash.



205
206
207
# File 'lib/blodsband/riak/bucket.rb', line 205

def [](key)
  self.get(key)
end

#[]=(key, value) ⇒ Blodsband::Riak::Response

Put a value in Riak.

Parameters:

  • key (String)

    the key to put the value under.

  • value (Object)

    the value to put under the key.

Returns:



116
117
118
# File 'lib/blodsband/riak/bucket.rb', line 116

def []=(key, value)
  self.put(key, value)
end

#aadd_index_rel(key, names, rel) ⇒ Blodsband::Riak::Future<Blodsband::Riak::Response>

Note:

The rel parameter can have a Hash as a third element containing extra attributes for the relationship. These attributes will be stored in the relationship document and can be used to filter queries on this relationship type. This is also usable from the #put method and will have the same effect there.

Add an index stored relation to Riak.

Right now this has proven meaningful up to relation sizes of about 10000 due to Riak Search limitations when it comes to how it counts and fetches documents. After that a clear linear scaling is observable.

Parameters:

  • key (String)

    the key for which to add the relation.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type for which to add a relation.

  • rel (Array<String, String>)

    the bucket and key to add to the relationship type.

Returns:



600
601
602
# File 'lib/blodsband/riak/bucket.rb', line 600

def aadd_index_rel(key, names, rel)
  Bucket.new(@url, names.sort.join("-")).aput(index_rel_key(key, names, rel), index_rel_document(names, key, rel))
end

#acas(key, value, expected_vclock, options = {}) ⇒ Blodsband::Future<Object>

Compare the value of a key to an expected vclock (or nil) and uniquely set a new value if the current value matches the expectations.

Parameters:

  • key (String)

    the key to look at.

  • value (Object)

    the value to put under the key.

  • expected_vclock (String)

    the vclock to replace, or nil if only set if the value is missing.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :client_id
    String

    client_id to use when communicating with Riak for this operation. Will default to the client_id of this Blodsband::Riak::Bucket.

Returns:

  • (Blodsband::Future<Object>)

    whatever this call eventually succeeded in inserting under key, or nil.



491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
# File 'lib/blodsband/riak/bucket.rb', line 491

def acas(key, value, expected_vclock, options = {})
  #
  # While result is :nothing we will continue working.
  #
  result = :nothing
  #
  # Remember the fiber that started it all
  #
  parent = Fiber.current
  #
  # Create a fiber that does our dirty work for us
  #
  Fiber.new do
    post_check_sleep = options.delete(:post_check_sleep)
    post_write_sleep = options.delete(:post_write_sleep)
    client_id = @defaults[:client_id] || rand(1 << 256).to_s(36)
    cas_id = rand(1 << 256).to_s(36)

    current = get(key)
    sleep(post_check_sleep) if post_check_sleep

    #
    # While we lack a result
    #
    while result == :nothing do
      if (expected_vclock.nil? && current.nil?) || (current.respond_to?(:vclock) && current.vclock == expected_vclock)
        #
        # The current value is what we expected, write our value and repeat with the response
        #
        current = put(key, 
                      value, 
                      :riak_params => {:w => :all, :returnbody => true}, 
                      :client_id => client_id,
                      :vclock => current.respond_to?(:vclock) ? current.vclock : nil,
                      :meta => {
                        "cas-state" => "prospect",
                        "cas-voter" => cas_id,
                        "cas-id" => cas_id
                      })
        sleep(post_write_sleep) if post_write_sleep
      else
        #
        # The current value was not what we expected, check what is the winner.
        #
        winner = find_winner(key, current, options.merge(:client_id => client_id,
                                                         :cas_voter => cas_id))
        if winner.nil?
          #
          # No winner, we tried to overwrite an existing value that didn't exist.
          #
          result = nil
        elsif winner.meta["cas-id"] == cas_id
          #
          # We are winners!
          #
          result = winner
        else
          #
          # We lost :/
          #           
          result = nil
        end
      end
    end
    #
    # Resume the parent if necessary.
    #
    parent.resume if parent.alive? && parent != Fiber.current
  end.resume
  return(Future.new do
           rval = nil
           Fiber.yield while result == :nothing
           result
         end)
end

#acount_index_rels(key, names) ⇒ Blodsband::Future<Integer>

Note:

The rel parameter can have a Hash as a third element containing extra attributes for the relationship. These attributes will be stored in the relationship document and can be used to filter queries on this relationship type. This is also usable from the #put method and will have the same effect there.

Count the number of relations of a given type.

Parameters:

  • key (String)

    the key for which to count relations.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type to count.

Returns:

  • (Blodsband::Future<Integer>)

    the number of matching relations eventually returned.



634
635
636
637
638
639
# File 'lib/blodsband/riak/bucket.rb', line 634

def acount_index_rels(key, names)
  future = Search.new(@url).asearch(create_search_expression(key, names), :index => names.sort.join("-"), :page => 1, :per_page => 1)
  return(Future.new do
           future.get[:total]
         end)
end

#add_index_rel(key, names, rel) ⇒ Blodsband::Riak::Response

Note:

The rel parameter can have a Hash as a third element containing extra attributes for the relationship. These attributes will be stored in the relationship document and can be used to filter queries on this relationship type. This is also usable from the #put method and will have the same effect there.

Add an index stored relation to Riak.

Right now this has proven meaningful up to relation sizes of about 10000 due to Riak Search limitations when it comes to how it counts and fetches documents. After that a clear linear scaling is observable.

Parameters:

  • key (String)

    the key for which to add the relation.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type for which to add a relation.

  • rel (Array<String, String>)

    the bucket and key to add to the relationship type.

Returns:



621
622
623
# File 'lib/blodsband/riak/bucket.rb', line 621

def add_index_rel(key, names, rel)
  aadd_index_rel(key, names, rel).get
end

#adelete(key, options = {}) ⇒ Blodsband::Future<Blodsband::Riak::Response>

Delete a key in Riak.

Parameters:

  • key (String)

    the key to delete.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :riak_params
    Hash<String, String>

    param_name => param_value of extra parameters to send to Riak when doing the HTTP request.

Returns:



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/blodsband/riak/bucket.rb', line 83

def adelete(key, options = {})
  riak_params = options.delete(:riak_params)
  m = Multi.new
  url = uri(key)
  url += "?#{riak_params.collect do |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" end.join("&")}" if riak_params
  m.add(:resp, EM::HttpRequest.new(url).adelete)
  return(Future.new do
           m.really_perform
           Response.parse(m)
         end)
end

#adelete_index_rel(key, names, rel) ⇒ Blodsband::Future<Blodsband::Riak::Response>

Remove an index stored relation from Riak.

Parameters:

  • key (String)

    the key from which to remove the relation.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type from which to remove a relation.

  • rel (Array<String, String>)

    the bucket and key to remove from the relationship type.

Returns:



574
575
576
# File 'lib/blodsband/riak/bucket.rb', line 574

def adelete_index_rel(key, names, rel) 
  Bucket.new(@url, names.sort.join("-")).adelete(index_rel_key(key, names, rel))
end

#aget(key, options = {}) ⇒ Blodsband::Future<Blodsband::Riak::Response>

Fetch a value from Riak.

Parameters:

  • key (String)

    the key from which to fetch the value.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :links
    Array<Array<String>>

    an Array of Riak link chains to fetch for the key. Example: artist.get(key, :links => [["aliases"], ["friends", "friends"]])

    :index_rels
    Array<Array<Symbol>>

    an Array of relationships stored as index relations to fetch for the key. Example: artist.get(key, :index_rels => [[:artists, :tracks], [:artists, :followers]])

    :unique
    true, false

    if true, any siblings returned from Riak will be reduced to one using a method that will return the currently likely winner in an ongoing #put_if_missing scenario.

    :ary
    true, false

    if true, will be guaranteed to return an Array containing zero or more values depending on the number of siblings and deleted values.

Returns:



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/blodsband/riak/bucket.rb', line 321

def aget(key, options = {})
  links = options.delete(:links)
  index_rels = options.delete(:index_rels)
  riak_params = options.delete(:riak_params)
  unique = options.include?(:unique) ? options.delete(:unique) : @defaults[:unique]
  ary = options.delete(:ary) || @defaults[:ary]
  raise "Unknown options to #{self.class}#get(#{key}, ...): #{options.inspect}" unless options.empty?
  u = uri(key)
  m = Multi.new
  if links
    links.each do |linkchain|
      m.add(linkchain, EM::HttpRequest.new("#{u}#{create_link_walker(linkchain)}").aget)
    end
  end
  mrs = []
  if index_rels
    index_rels.each do |names|
      mrs << aindex_rels(key, names)
    end
  end
  u += "?#{riak_params.collect do |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" end.join("&")}" if riak_params
  m.add(:resp, EM::HttpRequest.new(u).aget(:head => {"Accept" => "multipart/mixed, application/json"}))
  return(Future.new do
           m.really_perform
           resp = Response.parse(m, :links => links, :bucket => @name, :key => key)
           resp = find_winner(key, resp) if unique && resp && resp.status == 300
           resp = arify(resp) if ary
           rval = resp
           if mrs.size > 0
             unless resp.is_a?(Hash)
               rval = [resp]
             end
             class << resp
               attr_reader :index_rels
             end
             mrs.each_with_index do |mr, index|
               resp.instance_eval do
                 @index_rels ||= {}
                 @index_rels[index_rels[index]] = mr.get.collect do |hash| [hash["bucket"], hash["key"]] end
               end
               if resp.is_a?(Hash)
                 resp[index_rels[index][1].to_s] = mr.get.collect do |hash| extended_index_rel(hash) end
               else
                 rval << mr.get.collect do |hash| extended_index_rel(hash) end
               end
             end
           end
           rval
         end)
end

#aget_many(keys) ⇒ Blodsband::Future<Array<Blodsband::Riak::Response>>

Efficiently fetch values for many keys in Riak.

Parameters:

  • keys (Array)

    an Array of String containing the keys for which to fetch the values.

Returns:



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/blodsband/riak/bucket.rb', line 281

def aget_many(keys)
  Mr.new(@url).
    inputs(keys.collect do |key| [@name, key] end).
    map({
          :keep => false,
          :language => "javascript",
          :source => <<EOF
function(v,k,a) {
  if (v.values != null) {
    return [v];
  } else {
    return [];
  }
}
EOF
        }).
    reduce({
             :keep => true,
             :language => "javascript",
             :source => <<EOF
function(v) {
  rval = [];
  for (var i = 0; i < v.length; i++) {
    if (v[i].values != null) {
rval.push(JSON.parse(v[i].values[0].data));
    }
  }
  return rval;
}
EOF
           }).arun
end

#ahas_index_rel?(key, names, rel) ⇒ Blodsband::Future<true,false>

Check whether a given relation exists.

Parameters:

  • key (String)

    the key for which to check the relations.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type in which to search.

  • rel (Array<String, String>)

    the bucket and key to check if it exists in the relation type.

Returns:

  • (Blodsband::Future<true,false>)

    the eventual response to whether the relation exists.



662
663
664
665
666
667
# File 'lib/blodsband/riak/bucket.rb', line 662

def ahas_index_rel?(key, names, rel)
  future = Bucket.new(@url, names.sort.join("-")).aget(index_rel_key(key, names, rel))
  return(Future.new do
           !future.get.nil?
         end)
end

#ahas_many?(keys) ⇒ Blodsband::Future<Set<String>>

Efficiently check what keys correspond to existing values in Riak.

Parameters:

  • keys (Array<String>)

    an Array of String containing the keys for which to check if values exist.

Returns:

  • (Blodsband::Future<Set<String>>)

    a Set eventually containing the keys for which values exist.



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/blodsband/riak/bucket.rb', line 227

def ahas_many?(keys)
  future = Mr.new(@url).
    inputs(keys.collect do |key| [@name, key] end).
    map({
          :keep => false,
          :language => "javascript",
          :source => <<EOF
function(v,k,a) {
  if (v.values != null) {
    return [v];
  } else {
    return [];
  }
}
EOF
        }).
    reduce({
             :keep => true,
             :language => "javascript",
             :source => <<EOF
function(v) {
  rval = [];
  for (var i = 0; i < v.length; i++) {
    if (v[i].values != null) {
rval.push(v[i].key);
    }
  }
  return rval;
}
EOF
           }).arun
  return(Future.new do
           Set.new(future.get)
         end)
end

#aindex_rels(key, names) ⇒ Blodsband::Riak::Future<Array<Blodsband::Riak::Response>>

Note:

The names parameter can have a Hash as third element containing a filter definition :field => :required_value that will be used to filter the relations returned. This is also usable from the #get method and will have the same effect there.

Retrieve a set of relations stored in the Riak index.

Parameters:

  • key (String)

    the key to which the relations are connected.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type to fetch.

Returns:

  • (Blodsband::Riak::Future<Array<Blodsband::Riak::Response>>)

    a future containing an Array containing the eventually retrieved Responses stored in the index as these relations.



691
692
693
# File 'lib/blodsband/riak/bucket.rb', line 691

def aindex_rels(key, names)
  index_rel_mr(key, names).arun
end

#aput(key, value, options = {}) ⇒ Blodsband::Future<Blodsband::Riak::Response>

Put a value in Riak.

Parameters:

  • key (String)

    the key to put the value under.

  • value (Object)

    the value to insert under the key. If this Object responds to :vclock, :links, :index_rels or :meta the return values from those methods will be used as options in the resulting #put.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :links
    Hash<Symbol, Array<Array<String, String>>>

    tagname => [[bucket, key], [bucket, key], ...]. Will default to the #links of the value if available.

    :index_rels
    Hash<Array<Symbol, Symbol>, Array<Array<String, String>>>

    [i_am_to_relation, relation_is_to_me] => [[bucket, key], [bucket, key], ...]. Example: bucket.put(artist.key, artist, :links_rels => {[:artists, :tracks] => artist.track_refs}). Will default to the #index_rels of the value if available.

    :riak_params
    Hash<String, String>

    param_name => param_value of extra parameters to send to Riak when doing the HTTP request.

    :vclock
    String

    the vclock returned when the object was originally fetched. Will default to the #vclock of the value if available.

    :client_id
    String

    the client_id to use when communicating with Riak. Will default to the client_id of the Blodsband::Riak::Bucket.

    :meta
    Hash<String, String>

    meta_name => meta_value of Riak meta data to save with the object, that will be returned when fetching the value next time. Will default to the #meta of the value if available.

Returns:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/blodsband/riak/bucket.rb', line 127

def aput(key, value, options = {})
  links = value.links if value.respond_to?(:links)
  links = (links || {}).merge(options.delete(:links)) if options.include?(:links)
  
  index_rels = value.index_rels if value.respond_to?(:index_rels)
  index_rels = (index_rels || {}).merge(options.delete(:index_rels)) if options.include?(:index_rels)
  
  riak_params = options.delete(:riak_params)

  vclock = value.vclock if value.respond_to?(:vclock)
  vclock = options.delete(:vclock) if options.include?(:vclock)

  client_id = options.delete(:client_id) || @defaults[:client_id]

  meta = value.meta if value.respond_to?(:meta)
  meta = (meta || {}).merge(options.delete(:meta)) if options.include?(:meta)
  meta ||= {}

  raise "Unknown options to #{self.class}#put(#{key}, #{value}, ...): #{options.inspect}" unless options.empty?
  head = {
    "Content-Type" => "application/json",
    "Accept" => "multipart/mixed, application/json"
  }
  meta.each do |k, v|
    head["X-Riak-Meta-#{k}"] = v.to_s
  end
  head["X-Riak-ClientId"] = client_id if client_id
  head["Link"] = create_link_header(links) if links
  head["X-Riak-Vclock"] = vclock if vclock
  index_rel_futures = []
  if index_rels
    index_rels.each do |names, relations|
      relations.each do |rel|
        index_rel_futures << aadd_index_rel(key, names, rel)
      end
    end
  end
  url = uri(key)
  url += "?#{riak_params.collect do |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" end.join("&")}" if riak_params
  m = Multi.new
  m.add(:resp, 
        EM::HttpRequest.new(url).apost(:body => Yajl::Encoder.encode(value),
                                       :head => head))
  return(Future.new do
           m.really_perform
           index_rel_futures.each do |f|
             f.get
           end
           Response.parse(m, :bucket => @name, :key => key)
         end)
end

#aput_if_missing(key, value, options = {}) ⇒ Blodsband::Future<Object>

Put a value in the bucket if the key is missing.

Parameters:

  • key (String)

    the key to put the value under (if it doesn’t already exist).

  • value (Object)

    the value to put under the key (if the key doesn’t already exist).

  • options (Hash<Symbol, Object>) (defaults to: {})
    :client_id
    String

    client_id to use when communicating with Riak for this operation. Will default to the client_id of this Blodsband::Riak::Bucket.

Returns:

  • (Blodsband::Future<Object>)

    whatever this call eventually succeeded in inserting under key, or nil.



464
465
466
# File 'lib/blodsband/riak/bucket.rb', line 464

def aput_if_missing(key, value, options = {})
  acas(key, value, nil, options)
end

#arecip_index_rels(key, names) ⇒ Blodsband::Riak::Future<Array<Blodsband::Riak::Response>>

Note:

The names parameter can have a Hash as third element containing a filter definition :field => :required_value that will be used to filter the relations returned. This is also usable from the #get method and will have the same effect there.

Retrieve a set of relations having the same relation to us as we to them.

Parameters:

  • key (String)

    the key to which the relations are connected.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type to fetch.

Returns:

  • (Blodsband::Riak::Future<Array<Blodsband::Riak::Response>>)

    a future containing an Array containing the retrieved Blodsband::Riak:Responses stored in the index as these relations.



704
705
706
# File 'lib/blodsband/riak/bucket.rb', line 704

def arecip_index_rels(key, names)
  recip_index_rel_mr(key, names).arun
end

#cas(key, value, expected_vclock, options = {}) ⇒ Object

Compare the value of a key to an expected vclock (or nil) and uniquely set a new value if the current value matches the expectations.

Parameters:

  • key (String)

    the key to look at.

  • value (Object)

    the value to put under the key.

  • expected_vclock (String)

    the vclock to replace, or nil if only set if the value is missing.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :client_id
    String

    client_id to use when communicating with Riak for this operation. Will default to the client_id of this Blodsband::Riak::Bucket.

Returns:

  • (Object)

    whatever this call succeeded in inserting under key, or nil.



480
481
482
# File 'lib/blodsband/riak/bucket.rb', line 480

def cas(key, value, expected_vclock, options = {})
  acas(key, value, expected_vclock, options).get
end

#count_index_rels(key, names) ⇒ Integer

Note:

The rel parameter can have a Hash as a third element containing extra attributes for the relationship. These attributes will be stored in the relationship document and can be used to filter queries on this relationship type. This is also usable from the #put method and will have the same effect there.

Count the number of relations of a given type.

Parameters:

  • key (String)

    the key for which to count relations.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type to count.

Returns:

  • (Integer)

    the number of matching relations.



651
652
653
# File 'lib/blodsband/riak/bucket.rb', line 651

def count_index_rels(key, names)
  acount_index_rels(key, names).get
end

#counter(key) ⇒ Blodsband::Riak::Counter

Get a concurrent Counter in this Blodsband::Riak::Bucket.

Parameters:

  • key (String)

    the key for this counter.

Returns:



439
440
441
# File 'lib/blodsband/riak/bucket.rb', line 439

def counter(key)
  return Counter.new(self, key)
end

#delete(key, options = {}) ⇒ Blodsband::Riak::Response

Delete a key in Riak.

Parameters:

  • key (String)

    the key to delete.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :riak_params
    Hash<String, String>

    param_name => param_value of extra parameters to send to Riak when doing the HTTP request.

Returns:



104
105
106
# File 'lib/blodsband/riak/bucket.rb', line 104

def delete(key, options = {})
  adelete(key, options).get
end

#delete_index_rel(key, names, rel) ⇒ Blodsband::Riak::Response

Remove an index stored relation from Riak.

Parameters:

  • key (String)

    the key from which to remove the relation.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type from which to remove a relation.

  • rel (Array<String, String>)

    the bucket and key to remove from the relationship type.

Returns:

  • (Blodsband::Riak::Response)

    the eventual response from Riak for the resulting HTTP request (which will also be ie a String or a Hash.



587
588
589
# File 'lib/blodsband/riak/bucket.rb', line 587

def delete_index_rel(key, names, rel)
  adelete_index_rel(key, names, rel).get
end

#get(key, options = {}) ⇒ Blodsband::Riak::Response

Fetch a value from Riak.

Parameters:

  • key (String)

    the key from which to fetch the value.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :links
    Array<Array<String>>

    an Array of Riak link chains to fetch for the key. Example: artist.get(key, :links => [["aliases"], ["friends", "friends"]])

    :index_rels
    Array<Array<Symbol>>

    an Array of relationships stored as index relations to fetch for the key. Example: artist.get(key, :index_rels => [[:artists, :tracks], [:artists, :followers]])

    :unique
    true, false

    if true, any siblings returned from Riak will be reduced to one using a method that will return the currently likely winner in an ongoing #put_if_missing scenario.

    :ary
    true, false

    if true, will be guaranteed to return an Array containing zero or more values depending on the number of siblings and deleted values.

Returns:

  • (Blodsband::Riak::Response)

    the response from Riak for the resulting HTTP request (which will also be ie a String or a Hash.



384
385
386
# File 'lib/blodsband/riak/bucket.rb', line 384

def get(key, options = {})
  aget(key, options).get
end

#get_many(keys) ⇒ Array<Blodsband::Riak::Response>

Efficiently fetch values for many keys in Riak.

Parameters:

  • keys (Array)

    an Array of String containing the keys for which to fetch the values.

Returns:

  • (Array<Blodsband::Riak::Response>)

    the response from Riak for the resulting HTTP request (which will also be ie a Strings or a Hashes.



270
271
272
# File 'lib/blodsband/riak/bucket.rb', line 270

def get_many(keys)
  aget_many(keys).get
end

#has_index_rel?(key, names, rel) ⇒ true, false

Check whether a given relation exists.

Parameters:

  • key (String)

    the key for which to check the relations.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type in which to search.

  • rel (Array<String, String>)

    the bucket and key to check if it exists in the relation type.

Returns:

  • (true, false)

    whether the relation exists.



678
679
680
# File 'lib/blodsband/riak/bucket.rb', line 678

def has_index_rel?(key, names, rel)
  ahas_index_rel?(key, names, rel).get
end

#has_many?(keys) ⇒ Set<String>

Efficiently check what keys correspond to existing values in Riak.

Parameters:

  • keys (Array<String>)

    an Array of String containing the keys for which to check if values exist.

Returns:

  • (Set<String>)

    the keys having values.



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

def has_many?(keys)
  ahas_many?(keys).get
end

#index_rels(key, names) ⇒ Array<Blodsband::Riak::Response>

Note:

The names parameter can have a Hash as third element containing a filter definition :field => :required_value that will be used to filter the relations returned. This is also usable from the #get method and will have the same effect there.

Retrieve a set of relations stored in the Riak index.

Parameters:

  • key (String)

    the key to which the relations are connected.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type to fetch.

Returns:



734
735
736
# File 'lib/blodsband/riak/bucket.rb', line 734

def index_rels(key, names)
  aindex_rels(key, names).get
end

#indexedBlodsband::Riak::Bucket

Sets the Blodsband::Riak::Bucket property :search to true.

Returns:



53
54
55
56
# File 'lib/blodsband/riak/bucket.rb', line 53

def indexed
  self.props = {:search => true}
  self
end

#list(key) ⇒ Blodsband::Riak::List

Get a concurrent List in this Blodsband::Riak::Bucket.

Parameters:

  • key (String)

    the key for this list.

Returns:



406
407
408
# File 'lib/blodsband/riak/bucket.rb', line 406

def list(key)
  return List.new(self, key)
end

#lock(key) ⇒ Blodsband::Riak::Lock

Get a concurrent Tree in this Blodsband::Riak::Bucket.

Parameters:

  • key (String)

    the key for this lock.

Returns:



395
396
397
# File 'lib/blodsband/riak/bucket.rb', line 395

def lock(key)
  return Lock.new(self, key)
end

#map(key) ⇒ Blodsband::Riak::Map

Get a concurrent Map in this Blodsband::Riak::Bucket.

Parameters:

  • key (String)

    the key for this map.

Returns:



417
418
419
# File 'lib/blodsband/riak/bucket.rb', line 417

def map(key)
  return Map.new(self, key)
end

#propsHash<Symbol, Object>

Returns the properties of this Riak bucket.

Returns:

  • (Hash<Symbol, Object>)

    the properties of this Riak bucket.



61
62
63
# File 'lib/blodsband/riak/bucket.rb', line 61

def props
  Yajl::Parser.parse(EM::HttpRequest.new(uri).get.response)['props']
end

#props=(p) ⇒ Object

Sets the properties of this Riak bucket. Will merge in the given properties with the existing ones, so a complete property Hash is not necessary.

Parameters:

  • p (Hash<Symbol, Object>)

    the new properties.



71
72
73
74
# File 'lib/blodsband/riak/bucket.rb', line 71

def props=(p)
  EM::HttpRequest.new(uri).put(:head => {"Content-Type" => "application/json"},
                               :body => Yajl::Encoder.encode(:props => p))
end

#put(key, value, options = {}) ⇒ Blodsband::Riak::Response

Put a value in Riak.

Parameters:

  • key (String)

    the key to put the value under.

  • value (Object)

    the value to insert under the key. If this Object responds to :vclock, :links, :index_rels or :meta the return values from those methods will be used as options in the resulting #put.

  • options (Hash<Symbol, Object>) (defaults to: {})
    :links
    Hash<Symbol, Array<Array<String, String>>>

    tagname => [[bucket, key], [bucket, key], ...]. Will default to the #links of the value if available.

    :index_rels
    Hash<Array<Symbol, Symbol>, Array<Array<String, String>>>

    [i_am_to_relation, relation_is_to_me] => [[bucket, key], [bucket, key], ...]. Example: bucket.put(artist.key, artist, :links_rels => {[:artists, :tracks] => artist.track_refs}). Will default to the #index_rels of the value if available.

    :riak_params
    Hash<String, String>

    param_name => param_value of extra parameters to send to Riak when doing the HTTP request.

    :vclock
    String

    the vclock returned when the object was originally fetched. Will default to the #vclock of the value if available.

    :client_id
    String

    the client_id to use when communicating with Riak. Will default to the client_id of the Blodsband::Riak::Bucket.

    :meta
    Hash<String, String>

    meta_name => meta_value of Riak meta data to save with the object, that will be returned when fetching the value next time. Will default to the #meta of the value if available.

Returns:



194
195
196
# File 'lib/blodsband/riak/bucket.rb', line 194

def put(key, value, options = {})
  aput(key, value, options).get
end

#put_if_missing(key, value, options = {}) ⇒ Object

Put a value in the bucket if the key is missing.

Parameters:

  • key (String)

    the key to put the value under (if it doesn’t already exist).

  • value (Object)

    the value to put under the key (if the key doesn’t already exist).

  • options (Hash<Symbol, Object>) (defaults to: {})
    :client_id
    String

    client_id to use when communicating with Riak for this operation. Will default to the client_id of this Blodsband::Riak::Bucket.

Returns:

  • (Object)

    whatever this call succeeded in inserting under key, or nil.



453
454
455
# File 'lib/blodsband/riak/bucket.rb', line 453

def put_if_missing(key, value, options = {})
  aput_if_missing(key, value, options).get
end

#recip_index_rels(key, names) ⇒ Array<Blodsband::Riak::Response>

Note:

The names parameter can have a Hash as third element containing a filter definition :field => :required_value that will be used to filter the relations returned. This is also usable from the #get method and will have the same effect there.

Retrieve a set of relations having the same relation to us as we to them.

Parameters:

  • key (String)

    the key to which the relations are connected.

  • names (Array<Symbol, Symbol>)

    the specification of the relationship type to fetch.

Returns:

  • (Array<Blodsband::Riak::Response>)

    an Array containing the retrieved Blodsband::Riak:Responses stored in the index as these relations.



718
719
720
# File 'lib/blodsband/riak/bucket.rb', line 718

def recip_index_rels(key, names)
  arecip_index_rels(key, names).get
end

#sset(key) ⇒ Blodsband::Riak::Sset

Get a concurrent Sset in this Blodsband::Riak::Bucket.

Parameters:

  • key (String)

    the key for this set.

Returns:



428
429
430
# File 'lib/blodsband/riak/bucket.rb', line 428

def sset(key)
  return Sset.new(self, key)
end

#uniqueBlodsband::Riak::Bucket

Sets the Blodsband::Riak::Bucket property :allow_mult to true and the default option :unique to true.

Returns:



42
43
44
45
46
# File 'lib/blodsband/riak/bucket.rb', line 42

def unique
  @defaults[:unique] = true
  self.props = {:allow_mult => true}
  self
end