class Orchestrate::KeyValue

Key/Value pairs are pieces of data identified by a unique key for a collection and have corresponding value.

Attributes

collection[R]

The collection this KeyValue belongs to. @return [Orchestrate::Collection]

collection_name[R]

The name of the collection this KeyValue belongs to. @return [String]

id[R]

For comparison purposes only, the ‘address’ of this KeyValue item. Represented as “[collection_name]/” @return [String]

key[R]

The key for this KeyValue. @return [String]

last_request_time[R]

When the KeyValue was last loaded from Orchestrate. @return [Time]

path[R]

The ‘address’ of this KeyValue item, representated as #[collection_name]/# @return [String]

ref[R]

The ref for the current value for this KeyValue. @return [String]

reftime[R]

If known, the time at which this ref was created. @return [Time, nil]

value[RW]

The value for the KeyValue at this ref. @return [#to_json]

Public Class Methods

from_bodyless_response(collection, key, value, response) click to toggle source

Instantiate a KeyValue from a PUT or POST request and known value @param collection [Orchestrate::Collection] The collection to which the KeyValue belongs. @param key [#to_s] The key name. @param value [#to_json] The key’s value. @param response [Orchestrate::API::Response] The response that is associated with the PUT/POST. @return Orchestrate::KeyValue The KeyValue item.

# File lib/orchestrate/key_value.rb, line 24
def self.from_bodyless_response(collection, key, value, response)
  kv = new(collection, key, response)
  kv.value = value
  kv
end
from_listing(collection, listing, response) click to toggle source

Instantiate a KeyValue from a listing in a LIST or SEARCH result @param collection [Orchestrate::Collection] The collection to which the KeyValue belongs. @param listing [Hash] The entry in the LIST or SEARCH result @option listing [Hash] path required The path of the entry, with collection, key and ref keys. @option listing [Hash] value required The value for the entry @option listing [Time] reftime The time which the ref was created (only returned by LIST) @param response [Orchestrate::API::Response] The response which the listing came from @return Orchestrate::KeyValue The KeyValue item.

# File lib/orchestrate/key_value.rb, line 38
def self.from_listing(collection, listing, response)
  path = listing.fetch('path')
  key = path.fetch('key')
  ref = path.fetch('ref')
  kv = new(collection, key, response)
  kv.instance_variable_set(:@ref, ref)
  kv.instance_variable_set(:@reftime, listing['reftime']) if listing['reftime']
  kv.instance_variable_set(:@tombstone, path['tombstone'])
  kv.value = listing.fetch('value', nil)
  kv
end
load(collection, key) click to toggle source

Instantiates and loads a KeyValue item. @param collection [Orchestrate::Collection] The collection to which the KeyValue belongs. @param key [#to_s] The key name. @return Orchestrate::KeyValue The KeyValue item. @raise Orchestrate::API::NotFound if there is no value for the provided key.

# File lib/orchestrate/key_value.rb, line 12
def self.load(collection, key)
  kv = new(collection, key)
  kv.reload
  kv
end
new(coll, key_name, associated_response=nil) click to toggle source

Instantiates a new KeyValue item. You generally don’t want to call this yourself, but rather use the methods on Orchestrate::Collection to load a KeyValue. @param coll [Orchestrate::Collection] The collection to which this KeyValue belongs. @param key_name [#to_s] The name of the key @param associated_response [nil, Orchestrate::API::Response]

If an API::Response, used to load attributes and value.

@return Orchestrate::KeyValue

# File lib/orchestrate/key_value.rb, line 94
def initialize(coll, key_name, associated_response=nil)
  @collection = coll
  @collection_name = coll.name
  @app = coll.app
  @key = key_name.to_s
  @id = "#{collection_name}/#{key}"
  @path = "#{URI.escape(collection_name)}/#{URI.escape(key)}"
  @value = {}
  @ref = false
  load_from_response(associated_response) if associated_response
end

Public Instance Methods

<=>(other) click to toggle source

Equivalent to ‘String#<=>`. Compares by key and collection. @param other [Orchestrate::KeyValue] the KeyValue to compare against. @return [nil, -1, 0, 1]

# File lib/orchestrate/key_value.rb, line 119
def <=>(other)
  return nil unless other.kind_of?(Orchestrate::KeyValue)
  return nil unless other.collection == collection
  other.key <=> key
end
==(other) click to toggle source

Equivalent to ‘String#==`. Compares by key and collection. @param other [Orchestrate::KeyValue] the KeyValue to compare against. @return [true, false]

# File lib/orchestrate/key_value.rb, line 109
def ==(other)
  other.kind_of?(Orchestrate::KeyValue) && \
    other.collection == collection && \
    other.key == key
end
Also aliased as: eql?
[](attr_name) click to toggle source

Get an attribute from the KeyValue item’s value. @param attr_name [#to_s] The name of the attribute. @return [nil, true, false, Numeric, String, Array, Hash] the value for the attribute.

# File lib/orchestrate/key_value.rb, line 163
def [](attr_name)
  value[attr_name.to_s]
end
[]=(attr_name, attr_value) click to toggle source

Set a value to an attribute on the KeyValue item’s value. @param attr_name [#to_s] The name of the attribute. @param attr_value [#to_json] The new value for the attribute. @return [attr_value]

# File lib/orchestrate/key_value.rb, line 171
def []=(attr_name, attr_value)
  value[attr_name.to_s] = attr_value
end
add(path, value) click to toggle source

Adds a new field/value pair to a KeyValue at the designated path (field name). @param path [#to_s] The location of the field to add. @param value [#to_json] The value to assign to the specified field. @return Orchestrate::KeyValue::OperationSet

# File lib/orchestrate/key_value.rb, line 259
def add(path, value)
  OperationSet.new(self).add(path, value)
end
archival?() click to toggle source

Is this the “Current” value for this KeyValue? False for non-Ref objects. Use this instead of ‘#is_a?` or `#kind_of?`. @return [true, false]

# File lib/orchestrate/key_value.rb, line 146
def archival?
  false
end
copy(from_path, to_path) click to toggle source

Copies a KeyValue item’s field value to another field (path) @param from_path [#to_s] The field to copy. @param to_path [#to_s] The target location to copy field/value to. @raise Orchestrate::API::RequestError if field does not exist @return Orchestrate::KeyValue::OperationSet

# File lib/orchestrate/key_value.rb, line 293
def copy(from_path, to_path)
  OperationSet.new(self).copy(from_path, to_path)
end
dec(path, amount)
Alias for: decrement
decrement(path, amount) click to toggle source

Decreases a KeyValue item’s field number value by given amount @param path [#to_s] The field (with a number value) to decrement. @param amount [Integer] The amount to decrement the field’s value by. @raise Orchestrate::API::RequestError if field does not exist or if existing value is not a number type @return Orchestrate::KeyValue::OperationSet

# File lib/orchestrate/key_value.rb, line 314
def decrement(path, amount)
  OperationSet.new(self).decrement(path, amount)
end
Also aliased as: dec
destroy() click to toggle source

Deletes the KeyValue item from Orchestrate using ‘If-Match’ with the current ref. Returns false if the item failed to delete because a new ref had been created since this KeyValue was loaded. @return [true, false]

# File lib/orchestrate/key_value.rb, line 389
def destroy
  begin
    destroy!
  rescue API::VersionMismatch
    false
  end
end
destroy!() click to toggle source

Deletes a KeyValue item from Orchestrate using ‘If-Match’ with the current ref. @raise [Orchestrate::API::VersionMismatch] If the KeyValue item has been updated with a new ref since this KeyValue was loaded.

# File lib/orchestrate/key_value.rb, line 399
def destroy!
  response = perform(:delete, ref)
  @ref = nil
  @last_request_time = response.request_time
  true
end
eql?(other)
Alias for: ==
events() click to toggle source

Entry point for managing events associated with this KeyValue item. @return [Orchestrate::EventSource]

# File lib/orchestrate/key_value.rb, line 451
def events
  @events ||= EventSource.new(self)
end
inc(path, amount)
Alias for: increment
increment(path, amount) click to toggle source

Increases a KeyValue item’s field number value by given amount @param path [#to_s] The field (with a number value) to increment. @param amount [Integer] The amount to increment the field’s value by. @raise Orchestrate::API::RequestError if field does not exist or if existing value is not a number type @return Orchestrate::KeyValue::OperationSet

# File lib/orchestrate/key_value.rb, line 303
def increment(path, amount)
  OperationSet.new(self).increment(path, amount)
end
Also aliased as: inc
inspect()
Alias for: to_s
loaded?() click to toggle source

If the KeyValue has been loaded or not. @return [true, false] loaded

# File lib/orchestrate/key_value.rb, line 133
def loaded?
  !! last_request_time
end
merge(value, ref=nil) click to toggle source

Merges the given value into a KeyValue item using a patch request, enabling merges to be peformed without retrieving the KeyValue item. @param value [#to_json] Hash of partial values, to be converted to json, and merged into the KeyValue item. @param ref [String] optional condition, provide ref for ‘If-Match’ header

# File lib/orchestrate/key_value.rb, line 236
def merge(value, ref=nil)
  self.perform(:patch_merge, value, ref)
end
move(from_path, to_path) click to toggle source

Moves a KeyValue item’s field/value pair to a new field (path) @param from_path [#to_s] The field to move. @param to_path [#to_s] The new location of the moved field. @raise Orchestrate::API::RequestError if field does not exist @return Orchestrate::KeyValue::OperationSet

# File lib/orchestrate/key_value.rb, line 284
def move(from_path, to_path)
  OperationSet.new(self).move(from_path, to_path)
end
perform(api_method, *args) click to toggle source

Calls a method on the Collection’s Application’s client, providing the Collection’s name and KeyValue’s key. @param api_method [Symbol] The method on the client to call. @param args [#to_s, to_json, Hash] The arguments for the method. @return API::Response

# File lib/orchestrate/key_value.rb, line 462
def perform(api_method, *args)
  collection.perform(api_method, key, *args)
end
purge() click to toggle source

Deletes a KeyValue item and its entire Ref history from Orchestrate using ‘If-Match’ with the current ref. Returns false if the item failed to delete because a new ref had been created since this KeyValue was loaded. @return [true, false]

# File lib/orchestrate/key_value.rb, line 409
def purge
  begin
    purge!
  rescue API::VersionMismatch
    false
  end
end
purge!() click to toggle source

Deletes a KeyValue item and its entire Ref history from Orchestrate using ‘If-Match’ with the current ref. @raise [Orchestrate::API::VersionMismatch] If the KeyValue item has been updated with a new ref since this KeyValue was loaded.

# File lib/orchestrate/key_value.rb, line 419
def purge!
  response = perform(:purge, ref)
  @ref = nil
  @last_request_time = response.request_time
  true
end
refs() click to toggle source

Entry point for retrieving Refs associated with this KeyValue. @return [Orchestrate::RefList] A RefList instance bound to this KeyValue.

# File lib/orchestrate/key_value.rb, line 432
def refs
  @refs ||= RefList.new(self)
end
relations() click to toggle source

Entry point for managing the graph relationships for this KeyValue item @return [Orchestrate::Graph] A graph instance bound to this item.

# File lib/orchestrate/key_value.rb, line 442
def relations
  @relations ||= Graph.new(self)
end
reload() click to toggle source

Reload this KeyValue item from Orchestrate. @raise Orchestrate::API::NotFound if the KeyValue no longer exists.

# File lib/orchestrate/key_value.rb, line 139
def reload
  load_from_response(perform(:get))
end
remove(path) click to toggle source

Removes a field/value pair from a KeyValue item @param path [#to_s] The field to remove. @raise Orchestrate::API::RequestError if field does not exist

# File lib/orchestrate/key_value.rb, line 266
def remove(path)
  OperationSet.new(self).remove(path)
end
replace(path, value) click to toggle source

Replaces an existing field’s value @param path [#to_s] The field whose value to replace. @param value [#to_json] The value to assign to the specified field. @raise Orchestrate::API::RequestError if field does not exist @return Orchestrate::KeyValue::OperationSet

# File lib/orchestrate/key_value.rb, line 275
def replace(path, value)
  OperationSet.new(self).replace(path, value)
end
save() click to toggle source

Saves the KeyValue item to Orchestrate using ‘If-Match’ with the current ref. Sets the new ref for this value to the ref attribute. Returns false on failure to save, and rescues from all Orchestrate::API errors. @return [true, false]

# File lib/orchestrate/key_value.rb, line 183
def save
  begin
    save!
  rescue API::RequestError, API::ServiceError
    false
  end
end
save!() click to toggle source

Saves the KeyValue item to Orchestrate using ‘If-Match’ with the current ref. Sets the new ref for this value to the ref attribute. Raises an exception on failure to save. @return [true] @raise [Orchestrate::API::VersionMismatch] If the KeyValue item has been updated with a new ref since this KeyValue was loaded. @raise [Orchestrate::API::RequestError, Orchestrate::API::ServiceError] If there are any other problems with saving.

# File lib/orchestrate/key_value.rb, line 197
def save!
  begin
    load_from_response(perform(:put, value, ref))
    true
  rescue API::IndexingConflict => e
    @ref = e.response.headers['Location'].split('/').last
    @last_request_time = Time.parse(e.response.headers['Date'])
    true
  end
end
set(merge) click to toggle source

Merges a set of values into the item’s existing value and saves. @param merge [#each_pair] The Hash-like to merge into value. Keys will be stringified. @return [true, false]

# File lib/orchestrate/key_value.rb, line 211
def set(merge)
  begin
    set!(merge)
  rescue API::RequestError, API::ServiceError
    false
  end
end
set!(merge) click to toggle source

Merges a set of values into the item’s existing value and saves. @param merge [#each_pair] The Hash-like to merge into value. Keys will be stringified. @return [true] @raise [Orchestrate::API::VersionMismatch] If the KeyValue item has been updated with a new ref since this KeyValue was loaded. @raise [Orchestrate::API::RequestError, Orchestrate::API::ServiceError] If there was any other problem with saving.

# File lib/orchestrate/key_value.rb, line 224
def set!(merge)
  merge.each_pair {|key, value| @value[key.to_s] = value }
  save!
end
test(path, value) click to toggle source

Tests equality of a KeyValue’s existing field/value pair @param path [#to_s] The field to check equality of. @param value [#to_json] The expected value of the field. @raise Orchestrate::API::RequestError if field does not exist @raise Orchestrate::API::IndexingError if equality check fails @return Orchestrate::KeyValue::OperationSet

# File lib/orchestrate/key_value.rb, line 325
def test(path, value)
  OperationSet.new(self).test(path, value)
end
to_s() click to toggle source

@return Pretty-Printed string representation of the KeyValue

# File lib/orchestrate/key_value.rb, line 126
def to_s
  "#<Orchestrate::KeyValue id=#{id} ref=#{ref} last_request_time=#{last_request_time}>"
end
Also aliased as: inspect
tombstone?() click to toggle source

Is this a Ref that represents a null value (created through ‘#destroy` or similar)? False for most cases – The only way to retrieve a Ref for which this will return true is by enumerating trhough values from a RefList. @return [true, false]

# File lib/orchestrate/key_value.rb, line 154
def tombstone?
  !! @tombstone
end
update(ref=nil) click to toggle source

Manipulate a KeyValue item with a set of operations. Chain a series of operation methods (add, remove, etc) to build the set, operations will be executed by Orchestrate in sequential order. @param ref [String] optional condition, provide ref for ‘If-Match’ header To perform singular operations or a set, add update to the end of the method chain. @example

users['jon-snow'].add(:beard, true).remove(:some_field).update()

@raise Orchestrate::API::NotFound if key does not exist

# File lib/orchestrate/key_value.rb, line 251
def update(ref=nil)
  OperationSet.new(self).update(ref)
end

Private Instance Methods

load_from_response(response) click to toggle source
# File lib/orchestrate/key_value.rb, line 467
def load_from_response(response)
  response.on_complete do
    @ref = response.ref if response.respond_to?(:ref)
    @value = response.body unless response.body.respond_to?(:strip) && response.body.strip.empty?
    @last_request_time = response.request_time
  end
end