Class: Orchestrate::KeyValue

Inherits:
Object
  • Object
show all
Defined in:
lib/orchestrate/key_value.rb

Overview

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

Direct Known Subclasses

Ref

Defined Under Namespace

Classes: OperationSet

Instance Attribute Summary collapse

Attribute accessors collapse

Persistence collapse

patch-merge collapse

patch-operations collapse

refs collapse

relations collapse

events collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(coll, key_name, associated_response = nil) ⇒ Object

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.

Parameters:


94
95
96
97
98
99
100
101
102
103
104
# 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

Instance Attribute Details

#collectionOrchestrate::Collection (readonly)

The collection this KeyValue belongs to.


52
53
54
# File 'lib/orchestrate/key_value.rb', line 52

def collection
  @collection
end

#collection_nameString (readonly)

The name of the collection this KeyValue belongs to.

Returns:

  • (String)

56
57
58
# File 'lib/orchestrate/key_value.rb', line 56

def collection_name
  @collection_name
end

#idString (readonly)

For comparison purposes only, the 'address' of this KeyValue item. Represented as "[collection_name]/[key]"

Returns:

  • (String)

69
70
71
# File 'lib/orchestrate/key_value.rb', line 69

def id
  @id
end

#keyString (readonly)

The key for this KeyValue.

Returns:

  • (String)

60
61
62
# File 'lib/orchestrate/key_value.rb', line 60

def key
  @key
end

#last_request_timeTime (readonly)

When the KeyValue was last loaded from Orchestrate.

Returns:

  • (Time)

85
86
87
# File 'lib/orchestrate/key_value.rb', line 85

def last_request_time
  @last_request_time
end

#pathString (readonly)

The 'address' of this KeyValue item, representated as #[collection_name]/#[key]

Returns:

  • (String)

64
65
66
# File 'lib/orchestrate/key_value.rb', line 64

def path
  @path
end

#refString (readonly)

The ref for the current value for this KeyValue.

Returns:

  • (String)

73
74
75
# File 'lib/orchestrate/key_value.rb', line 73

def ref
  @ref
end

#reftimeTime? (readonly)

If known, the time at which this ref was created.

Returns:

  • (Time, nil)

77
78
79
# File 'lib/orchestrate/key_value.rb', line 77

def reftime
  @reftime
end

#value#to_json

The value for the KeyValue at this ref.

Returns:

  • (#to_json)

81
82
83
# File 'lib/orchestrate/key_value.rb', line 81

def value
  @value
end

Class Method Details

.from_bodyless_response(collection, key, value, response) ⇒ Object

Instantiate a KeyValue from a PUT or POST request and known value

Parameters:

Returns:

  • Orchestrate::KeyValue The KeyValue item.


24
25
26
27
28
# 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) ⇒ Object

Instantiate a KeyValue from a listing in a LIST or SEARCH result

Parameters:

Options Hash (listing):

  • path (Hash)

    required The path of the entry, with collection, key and ref keys.

  • value (Hash)

    required The value for the entry

  • reftime (Time)

    The time which the ref was created (only returned by LIST)

Returns:

  • Orchestrate::KeyValue The KeyValue item.


38
39
40
41
42
43
44
45
46
47
48
# 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) ⇒ Object

Instantiates and loads a KeyValue item.

Parameters:

Returns:

  • Orchestrate::KeyValue The KeyValue item.

Raises:

  • Orchestrate::API::NotFound if there is no value for the provided key.


12
13
14
15
16
# File 'lib/orchestrate/key_value.rb', line 12

def self.load(collection, key)
  kv = new(collection, key)
  kv.reload
  kv
end

Instance Method Details

#<=>(other) ⇒ nil, ...

Equivalent to String#<=>. Compares by key and collection.

Parameters:

Returns:

  • (nil, -1, 0, 1)

119
120
121
122
123
# 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) ⇒ true, false Also known as: eql?

Equivalent to String#==. Compares by key and collection.

Parameters:

Returns:

  • (true, false)

109
110
111
112
113
# File 'lib/orchestrate/key_value.rb', line 109

def ==(other)
  other.kind_of?(Orchestrate::KeyValue) && \
    other.collection == collection && \
    other.key == key
end

#[](attr_name) ⇒ nil, ...

Get an attribute from the KeyValue item's value.

Parameters:

  • attr_name (#to_s)

    The name of the attribute.

Returns:

  • (nil, true, false, Numeric, String, Array, Hash)

    the value for the attribute.


163
164
165
# File 'lib/orchestrate/key_value.rb', line 163

def [](attr_name)
  value[attr_name.to_s]
end

#[]=(attr_name, attr_value) ⇒ attr_value

Set a value to an attribute on the KeyValue item's value.

Parameters:

  • attr_name (#to_s)

    The name of the attribute.

  • attr_value (#to_json)

    The new value for the attribute.

Returns:

  • (attr_value)

171
172
173
# File 'lib/orchestrate/key_value.rb', line 171

def []=(attr_name, attr_value)
  value[attr_name.to_s] = attr_value
end

#add(path, value) ⇒ Object

Adds a new field/value pair to a KeyValue at the designated path (field name).

Parameters:

  • path (#to_s)

    The location of the field to add.

  • value (#to_json)

    The value to assign to the specified field.

Returns:

  • Orchestrate::KeyValue::OperationSet


259
260
261
# File 'lib/orchestrate/key_value.rb', line 259

def add(path, value)
  OperationSet.new(self).add(path, value)
end

#archival?true, false

Is this the "Current" value for this KeyValue? False for non-Ref objects. Use this instead of #is_a? or #kind_of?.

Returns:

  • (true, false)

146
147
148
# File 'lib/orchestrate/key_value.rb', line 146

def archival?
  false
end

#copy(from_path, to_path) ⇒ Object

Copies a KeyValue item's field value to another field (path)

Parameters:

  • from_path (#to_s)

    The field to copy.

  • to_path (#to_s)

    The target location to copy field/value to.

Returns:

  • Orchestrate::KeyValue::OperationSet

Raises:

  • Orchestrate::API::RequestError if field does not exist


293
294
295
# File 'lib/orchestrate/key_value.rb', line 293

def copy(from_path, to_path)
  OperationSet.new(self).copy(from_path, to_path)
end

#decrement(path, amount) ⇒ Object Also known as: dec

Decreases a KeyValue item's field number value by given amount if existing value is not a number type

Parameters:

  • path (#to_s)

    The field (with a number value) to decrement.

  • amount (Integer)

    The amount to decrement the field's value by.

Returns:

  • Orchestrate::KeyValue::OperationSet

Raises:

  • Orchestrate::API::RequestError if field does not exist or


314
315
316
# File 'lib/orchestrate/key_value.rb', line 314

def decrement(path, amount)
  OperationSet.new(self).decrement(path, amount)
end

#destroytrue, false

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.

Returns:

  • (true, false)

389
390
391
392
393
394
395
# File 'lib/orchestrate/key_value.rb', line 389

def destroy
  begin
    destroy!
  rescue API::VersionMismatch
    false
  end
end

#destroy!Object

Deletes a KeyValue item from Orchestrate using 'If-Match' with the current ref.

Raises:


399
400
401
402
403
404
# File 'lib/orchestrate/key_value.rb', line 399

def destroy!
  response = perform(:delete, ref)
  @ref = nil
  @last_request_time = response.request_time
  true
end

#eventsOrchestrate::EventSource

Entry point for managing events associated with this KeyValue item.


451
452
453
# File 'lib/orchestrate/key_value.rb', line 451

def events
  @events ||= EventSource.new(self)
end

#increment(path, amount) ⇒ Object Also known as: inc

Increases a KeyValue item's field number value by given amount if existing value is not a number type

Parameters:

  • path (#to_s)

    The field (with a number value) to increment.

  • amount (Integer)

    The amount to increment the field's value by.

Returns:

  • Orchestrate::KeyValue::OperationSet

Raises:

  • Orchestrate::API::RequestError if field does not exist or


303
304
305
# File 'lib/orchestrate/key_value.rb', line 303

def increment(path, amount)
  OperationSet.new(self).increment(path, amount)
end

#loaded?true, false

If the KeyValue has been loaded or not.

Returns:

  • (true, false)

    loaded


133
134
135
# File 'lib/orchestrate/key_value.rb', line 133

def loaded?
  !! last_request_time
end

#merge(value, ref = nil) ⇒ Object

Merges the given value into a KeyValue item using a patch request, enabling merges to be peformed without retrieving the KeyValue item. and merged into the KeyValue item.

Parameters:

  • value (#to_json)

    Hash of partial values, to be converted to json,

  • ref (String) (defaults to: nil)

    optional condition, provide ref for 'If-Match' header


236
237
238
# 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) ⇒ Object

Moves a KeyValue item's field/value pair to a new field (path)

Parameters:

  • from_path (#to_s)

    The field to move.

  • to_path (#to_s)

    The new location of the moved field.

Returns:

  • Orchestrate::KeyValue::OperationSet

Raises:

  • Orchestrate::API::RequestError if field does not exist


284
285
286
# 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) ⇒ Object

Calls a method on the Collection's Application's client, providing the Collection's name and KeyValue's key.

Parameters:

  • api_method (Symbol)

    The method on the client to call.

  • args (#to_s, #to_json, Hash)

    The arguments for the method.

Returns:

  • API::Response


462
463
464
# File 'lib/orchestrate/key_value.rb', line 462

def perform(api_method, *args)
  collection.perform(api_method, key, *args)
end

#purgetrue, false

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.

Returns:

  • (true, false)

409
410
411
412
413
414
415
# File 'lib/orchestrate/key_value.rb', line 409

def purge
  begin
    purge!
  rescue API::VersionMismatch
    false
  end
end

#purge!Object

Deletes a KeyValue item and its entire Ref history from Orchestrate using 'If-Match' with the current ref.

Raises:


419
420
421
422
423
424
# File 'lib/orchestrate/key_value.rb', line 419

def purge!
  response = perform(:purge, ref)
  @ref = nil
  @last_request_time = response.request_time
  true
end

#refsOrchestrate::RefList

Entry point for retrieving Refs associated with this KeyValue.

Returns:


432
433
434
# File 'lib/orchestrate/key_value.rb', line 432

def refs
  @refs ||= RefList.new(self)
end

#relationsOrchestrate::Graph

Entry point for managing the graph relationships for this KeyValue item

Returns:


442
443
444
# File 'lib/orchestrate/key_value.rb', line 442

def relations
  @relations ||= Graph.new(self)
end

#reloadObject

Reload this KeyValue item from Orchestrate.

Raises:

  • Orchestrate::API::NotFound if the KeyValue no longer exists.


139
140
141
# File 'lib/orchestrate/key_value.rb', line 139

def reload
  load_from_response(perform(:get))
end

#remove(path) ⇒ Object

Removes a field/value pair from a KeyValue item

Parameters:

  • path (#to_s)

    The field to remove.

Raises:

  • Orchestrate::API::RequestError if field does not exist


266
267
268
# File 'lib/orchestrate/key_value.rb', line 266

def remove(path)
  OperationSet.new(self).remove(path)
end

#replace(path, value) ⇒ Object

Replaces an existing field's value

Parameters:

  • path (#to_s)

    The field whose value to replace.

  • value (#to_json)

    The value to assign to the specified field.

Returns:

  • Orchestrate::KeyValue::OperationSet

Raises:

  • Orchestrate::API::RequestError if field does not exist


275
276
277
# File 'lib/orchestrate/key_value.rb', line 275

def replace(path, value)
  OperationSet.new(self).replace(path, value)
end

#savetrue, false

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.

Returns:

  • (true, false)

183
184
185
186
187
188
189
# File 'lib/orchestrate/key_value.rb', line 183

def save
  begin
    save!
  rescue API::RequestError, API::ServiceError
    false
  end
end

#save!true

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.

Returns:

  • (true)

Raises:


197
198
199
200
201
202
203
204
205
206
# 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) ⇒ true, false

Merges a set of values into the item's existing value and saves.

Parameters:

  • merge (#each_pair)

    The Hash-like to merge into #value. Keys will be stringified.

Returns:

  • (true, false)

211
212
213
214
215
216
217
# File 'lib/orchestrate/key_value.rb', line 211

def set(merge)
  begin
    set!(merge)
  rescue API::RequestError, API::ServiceError
    false
  end
end

#set!(merge) ⇒ true

Merges a set of values into the item's existing value and saves.

Parameters:

  • merge (#each_pair)

    The Hash-like to merge into #value. Keys will be stringified.

Returns:

  • (true)

Raises:


224
225
226
227
# 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) ⇒ Object

Tests equality of a KeyValue's existing field/value pair

Parameters:

  • path (#to_s)

    The field to check equality of.

  • value (#to_json)

    The expected value of the field.

Returns:

  • Orchestrate::KeyValue::OperationSet

Raises:

  • Orchestrate::API::RequestError if field does not exist

  • Orchestrate::API::IndexingError if equality check fails


325
326
327
# File 'lib/orchestrate/key_value.rb', line 325

def test(path, value)
  OperationSet.new(self).test(path, value)
end

#to_sObject Also known as: inspect

Returns Pretty-Printed string representation of the KeyValue.

Returns:

  • Pretty-Printed string representation of the KeyValue


126
127
128
# File 'lib/orchestrate/key_value.rb', line 126

def to_s
  "#<Orchestrate::KeyValue id=#{id} ref=#{ref} last_request_time=#{last_request_time}>"
end

#tombstone?true, false

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.

Returns:

  • (true, false)

154
155
156
# File 'lib/orchestrate/key_value.rb', line 154

def tombstone?
  !! @tombstone
end

#update(ref = nil) ⇒ Object

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. To perform singular operations or a set, add #update to the end of the method chain.

Examples:

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

Parameters:

  • ref (String) (defaults to: nil)

    optional condition, provide ref for 'If-Match' header

Raises:

  • Orchestrate::API::NotFound if key does not exist


251
252
253
# File 'lib/orchestrate/key_value.rb', line 251

def update(ref=nil)
  OperationSet.new(self).update(ref)
end