Class: MemStore::ObjectStore

Inherits:
Object
  • Object
show all
Defined in:
lib/memstore/objectstore.rb,
lib/memstore/queries.rb

Overview

An ObjectStore accesses item attributes through item#attribute.

Direct Known Subclasses

HashStore

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key = nil, items = {}) ⇒ ObjectStore

Initializes an ObjectStore.

key - Optional Symbol or String naming the method to obtain an item’s key attribute (default: nil).

When no key is specified, Object#hash will be used for uniquely identifying items.

items - Optional Hash of items to initialize the data store with (default: empty Hash).

Examples

store = ObjectStore.new
store = ObjectStore.new(:id)
store = ObjectStore.new(nil, { a.hash => a, b.hash => b, c.hash => c })
store = ObjectStore.new(:id, { 1 => a, 2 => b, 3 => c })

Returns initialized ObjectStore.



22
23
24
25
# File 'lib/memstore/objectstore.rb', line 22

def initialize(key=nil, items={})
  @key = key || :hash
  @items = items
end

Instance Attribute Details

#itemsObject

Provides access to internal items collection (which is simply a Hash).



28
29
30
# File 'lib/memstore/objectstore.rb', line 28

def items
  @items
end

Class Method Details

.from_binary(binary) ⇒ Object

Restores a data store from binary format.

binary - Binary data containing a serialized instance of ObjectStore.

Examples

store = ObjectStore.from_binary(IO.read(file))

Returns instance of ObjectStore

or nil if marshalling failed or marshalled object isn

Raises whatever Marshal::load raises.



158
159
160
161
# File 'lib/memstore/objectstore.rb', line 158

def self.from_binary(binary)
  restored = Marshal.load(binary) rescue nil
  if restored.instance_of?(ObjectStore) then restored else nil end
end

.from_file(file) ⇒ Object

Restores a data store from a binary file.

file - IO stream or file name as String.

Examples

store = ObjectStore.from_file(file)

Returns instance of ObjectStore or nil (result of ::from_binary)

or nil if file IO failed, e.g. because file doesn

Raises whatever IO::read or Marshal::load raise.



174
175
176
# File 'lib/memstore/objectstore.rb', line 174

def self.from_file(file)
  self.from_binary(IO.read(file)) rescue nil
end

.with_file(file, key = nil, items = {}, &block) ⇒ Object

Executes a given block while keeping an exclusive lock on a file. Allows to use the same file for persistence from multiple threads/processes. Tries to deserialize a data store from the file using ::from_file. If that fails, a new one will be created using the supplied key and items. Writes data store back to file using #to_file after block returns.

file - IO stream or file name as String. key - Optional key attribute (Symbol or String) to use in ::new (default: nil). items - Optional items Hash to use in ::new (default: empty Hash). block - Block that will be called after a data store was restored or created.

Yields the restored or newly created data store.

Examples

size_after_changes = ObjectStore.with_file(file, :id) do |store|
  store.delete(a, b, c, d, e)
  store.insert(f, g, h)
  store.size
end

Returns whatever the block returns. Raises whatever File::open, IO::read, Marshal::load, Marshal::dump or IO::write raise.



201
202
203
# File 'lib/memstore/objectstore.rb', line 201

def self.with_file(file, key=nil, items={}, &block)
  self.execute_with_file(:from_file, :to_file, file, key, items, &block)
end

Instance Method Details

#[](*keys) ⇒ Object

Retrieves one or more items by key.

keys - One or more Objects or Ranges that are keys of items.

For a Range, all items with keys in that range are returned.

Examples

store[1]
store[1, 2, 3]
store[1..3]
store[1, 3..5, 7]

Returns an Object if a single key was given

or nil if no item with that key exists
or an Array of Objects when multiple keys were given
in which nil is placed wherever there isn


71
72
73
74
75
76
77
# File 'lib/memstore/objectstore.rb', line 71

def [](*keys)
  return @items[keys.first] if keys.length == 1 && !keys.first.is_a?(Range)
  keys.inject([]) do |items, key|
    if key.is_a?(Range) then key.inject(items) { |i, k| i << @items[k] }
    else items << @items[key] end
  end
end

#allObject

Returns all items as an Array.



80
81
82
# File 'lib/memstore/objectstore.rb', line 80

def all
  @items.values
end

#count_all(conditions = {}, &block) ⇒ Object Also known as: count

Also available as #count. Returns the number of items that fulfill all conditions.



81
82
83
# File 'lib/memstore/queries.rb', line 81

def count_all(conditions={}, &block)
  all.count { |item| instance_exec(item, conditions, block, &FIND_ALL) }
end

#count_any(conditions = {}, &block) ⇒ Object

Returns the number of items that fulfill at least one condition.



87
88
89
# File 'lib/memstore/queries.rb', line 87

def count_any(conditions={}, &block)
  all.count { |item| instance_exec(item, conditions, block, &FIND_ANY) }
end

#count_none(conditions = {}, &block) ⇒ Object

Returns the number of items that violate all conditions.



103
104
105
# File 'lib/memstore/queries.rb', line 103

def count_none(conditions={}, &block)
  all.count { |item| instance_exec(item, conditions, block, &FIND_NONE) }
end

#count_not_all(conditions = {}, &block) ⇒ Object

which is equivalent to: !condition || !condition || … [|| !block] Returns the number of items that violate at least one condition.



98
99
100
# File 'lib/memstore/queries.rb', line 98

def count_not_all(conditions={}, &block)
  all.count { |item| !instance_exec(item, conditions, block, &FIND_ALL) }
end

#count_one(conditions = {}, &block) ⇒ Object

Returns the number of items that fulfill exactly one condition.



92
93
94
# File 'lib/memstore/queries.rb', line 92

def count_one(conditions={}, &block)
  all.count { |item| instance_exec(item, conditions, block, &FIND_ONE) }
end

#delete_items(*items) ⇒ Object Also known as: delete_item, delete

Deletes one or more items by reference. Also available as #delete_item and #delete.

items - One or more Objects that respond to the method specified as key attribute.

Examples

store.delete_item(a)
store.delete_items(a, b, c)
store.delete(a)
store.delete(a, b, c)

Returns the Object that was removed if a single item was given

or nil if the item isn


99
100
101
102
# File 'lib/memstore/objectstore.rb', line 99

def delete_items(*items)
  return @items.delete(key(items.first)) if items.length == 1
  items.collect { |item| @items.delete(key(item)) }
end

#delete_keys(*keys) ⇒ Object Also known as: delete_key

Deletes one or more items by key. Also available as #delete_key.

keys - One or more Objects or Ranges that are keys of items.

For a Range, all items with keys in that range are deleted.

Examples

store.delete_key(1)
store.delete_keys(1, 2, 3)
store.delete_keys(1..3)
store.delete_keys(1, 3..5, 7)

Returns the Object that was removed if a single key was given

or nil if no item with that key exists
or an Array of Objects that were removed when multiple keys were given
in which nil is placed wherever there isn


122
123
124
125
126
127
128
# File 'lib/memstore/objectstore.rb', line 122

def delete_keys(*keys)
  return @items.delete(keys.first) if keys.length == 1 && !keys.first.is_a?(Range)
  keys.inject([]) do |items, key|
    if key.is_a?(Range) then key.inject(items) { |i, k| i << @items.delete(k) }
    else items << @items.delete(key) end
  end
end

#find_all(conditions = {}, &block) ⇒ Object Also known as: find

Also available as #find. Returns an Array of items that fulfill all conditions.



22
23
24
# File 'lib/memstore/queries.rb', line 22

def find_all(conditions={}, &block)
  all.select { |item| instance_exec(item, conditions, block, &FIND_ALL) }
end

#find_any(conditions = {}, &block) ⇒ Object

Returns an Array of items that fulfill at least one condition.



28
29
30
# File 'lib/memstore/queries.rb', line 28

def find_any(conditions={}, &block)
  all.select { |item| instance_exec(item, conditions, block, &FIND_ANY) }
end

#find_none(conditions = {}, &block) ⇒ Object

Returns an Array of items that violate all conditions.



43
44
45
# File 'lib/memstore/queries.rb', line 43

def find_none(conditions={}, &block)
  all.select { |item| instance_exec(item, conditions, block, &FIND_NONE) }
end

#find_not_all(conditions = {}, &block) ⇒ Object

Returns an Array of items that violate at least one condition.



38
39
40
# File 'lib/memstore/queries.rb', line 38

def find_not_all(conditions={}, &block)
  all.reject { |item| instance_exec(item, conditions, block, &FIND_ALL) }
end

#find_one(conditions = {}, &block) ⇒ Object

Returns an Array of items that fulfill exactly one condition.



33
34
35
# File 'lib/memstore/queries.rb', line 33

def find_one(conditions={}, &block)
  all.select { |item| instance_exec(item, conditions, block, &FIND_ONE) }
end

#first_all(conditions = {}, &block) ⇒ Object Also known as: first

Also available as #first. Returns the first item that fulfills all conditions.



51
52
53
# File 'lib/memstore/queries.rb', line 51

def first_all(conditions={}, &block)
  all.detect { |item| instance_exec(item, conditions, block, &FIND_ALL) }
end

#first_any(conditions = {}, &block) ⇒ Object

Returns the first item that fulfills at least one condition.



57
58
59
# File 'lib/memstore/queries.rb', line 57

def first_any(conditions={}, &block)
  all.detect { |item| instance_exec(item, conditions, block, &FIND_ANY) }
end

#first_none(conditions = {}, &block) ⇒ Object

Returns the first item that violates all conditions.



73
74
75
# File 'lib/memstore/queries.rb', line 73

def first_none(conditions={}, &block)
  all.detect { |item| instance_exec(item, conditions, block, &FIND_NONE) }
end

#first_not_all(conditions = {}, &block) ⇒ Object

which is equivalent to: !condition || !condition || … [|| !block] Returns the first item that violates at least one condition.



68
69
70
# File 'lib/memstore/queries.rb', line 68

def first_not_all(conditions={}, &block)
  all.detect { |item| !instance_exec(item, conditions, block, &FIND_ALL) }
end

#first_one(conditions = {}, &block) ⇒ Object

Returns the first item that fulfills exactly one condition.



62
63
64
# File 'lib/memstore/queries.rb', line 62

def first_one(conditions={}, &block)
  all.detect { |item| instance_exec(item, conditions, block, &FIND_ONE) }
end

#insert(*items) ⇒ Object Also known as: <<

Inserts one or more items into the data store, can be chained. Also available as #<<, which only allows for one item at a time.

items - One or more Objects that respond to the method specified as key attribute.

Examples

store.insert(a).insert(b).insert(c)
store.insert(a, b, c)
store << a << b << c

Returns the data store itself to enable chaining. Raises NoMethodError when an item does’t respond to the key attribute method.



43
44
45
46
# File 'lib/memstore/objectstore.rb', line 43

def insert(*items)
  items.each { |item| @items[key(item)] = item }
  self
end

#lengthObject Also known as: size

Returns total number of items in the data store. Also available as #size.



50
51
52
# File 'lib/memstore/objectstore.rb', line 50

def length
  @items.length
end

#to_binaryObject

Returns data store in binary format. Raises whatever Marshal::dump raises.



133
134
135
# File 'lib/memstore/objectstore.rb', line 133

def to_binary
  Marshal.dump(self)
end

#to_file(file) ⇒ Object

Writes data store to a file in binary format.

file - IO stream of file name as String.

Returns number of bytes that were written to the file. Raises whatever IO::write raises.



143
144
145
# File 'lib/memstore/objectstore.rb', line 143

def to_file(file)
  IO.write(file, self.to_binary)
end