Решение на Пета задача - DataModel от Емине Башева

Обратно към всички решения

Към профила на Емине Башева

Резултати

  • 1 точка от тестове
  • 0 бонус точки
  • 1 точка общо
  • 4 успешни тест(а)
  • 21 неуспешни тест(а)

Код

class DataModel
attr_accessor :id
def initialize
@id = nil
end
def save
end
def delete
end
def self.attributes
end
def self.data_store
end
end
module DataStore
class << self
def update_record(record, attrs)
attrs.each do |attr_key, attr_value|
record[attr_key] = attr_value
end
end
def suitable_record?(record, query)
is_contained = query.select do |attr_key, attr_value|
(record.key? attr_key) && (record[attr_key] == attr_value)
end
is_contained.all?
end
end
end
class ArrayStore
attr_reader :storage
def initialize
@storage = []
end
def create(record)
@storage << record
end
def find(query)
result = []
@storage.each do |record|
result << record if DataStore.suitable_record? record, query
end
result
end
def update(id, attrs)
@storage.each do |record|
DataStore.update_record(record, attrs) if record[:id] == id
end
end
def delete(query)
@storage.delete_if do |record|
DataStore.suitable_record? record, query
end
end
end
class HashStore
attr_reader :storage
def initialize
@storage = {}
end
def create(record)
@storage[record[:id]] = record
end
def find(query)
result = []
@storage.each do |_, record|
result << record if DataStore.suitable_record? record, query
end
result
end
def update(id, attrs)
DataStore.update_record(@storage[id], attrs)
end
def delete(query)
@storage.delete_if do |_, record|
DataStore.suitable_record? record, query
end
end
end

Лог от изпълнението

FFFFFFFFFFFFFFF.F.FF.F.FF

Failures:

  1) DataModel creates attribute accessors
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:13:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) DataModel has attributes and data_model getters
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:22:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) DataModel accepts attributes when initializing
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:28:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  4) DataModel has #find_by_<attribute> methods
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:40:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  5) DataModel id generation creates id on first save and does not change it
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:49:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  6) DataModel id generation does not reuse ids
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:63:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  7) DataModel id generation does not break when there are two models with the same store
     Failure/Error: attributes :first_name
     ArgumentError:
       wrong number of arguments (given 1, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:77:in `block (4 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:76:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:76:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:76:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  8) DataModel equality comparison compares by id if both records are saved
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:93:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  9) DataModel equality comparison uses #equal? if there are no ids
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:109:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  10) DataModel.where finds records by attributes
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:119:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  11) DataModel.where finds records by multiple attributes
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:119:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  12) DataModel.where returns empty collection when nothing is found
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:119:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  13) DataModel.where raises an error if the query is by an unknown key
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:119:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  14) DataModel#delete deletes only the record for which it is called
     Failure/Error: attributes :first_name, :last_name, :age
     ArgumentError:
       wrong number of arguments (given 3, expected 0)
     # /tmp/d20161202-15620-1e3ilh7/solution.rb:16:in `attributes'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:7:in `block (3 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `initialize'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `new'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:6:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:152:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  15) DataModel#delete raises an error if the record is not saved
     Failure/Error: DataModel::DeleteUnsavedRecordError
     NameError:
       uninitialized constant DataModel::DeleteUnsavedRecordError
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:164:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  16) HashStore behaves like a data store #find can find elements by attributes
     Failure/Error: expect(store.find(id: 1)).to be_empty
       expected empty? to return true, got false
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1e3ilh7/spec.rb:235
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:190:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  17) HashStore behaves like a data store #update only updates records with the correct IDs
     Failure/Error: expect(store.find(id: 1)).to eq [georgi]
       
       expected: [{:id=>1, :name=>"Georgi"}]
            got: [{:id=>1, :name=>"Georgi"}, {:id=>2, :name=>"Sasho"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>1, :name=>"Georgi"}]
       +[{:id=>1, :name=>"Georgi"}, {:id=>2, :name=>"Sasho"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1e3ilh7/spec.rb:235
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:212:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  18) HashStore behaves like a data store #delete can delete multiple records with a single query
     Failure/Error: expect(store.find({})).to eq [gosho]
       
       expected: [{:id=>3, :name=>"Gosho"}]
            got: []
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>3, :name=>"Gosho"}]
       +[]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1e3ilh7/spec.rb:235
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:229:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  19) ArrayStore behaves like a data store #find can find elements by attributes
     Failure/Error: expect(store.find(id: 1)).to be_empty
       expected empty? to return true, got false
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1e3ilh7/spec.rb:239
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:190:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  20) ArrayStore behaves like a data store #update only updates records with the correct IDs
     Failure/Error: expect(store.find(id: 1)).to eq [georgi]
       
       expected: [{:id=>1, :name=>"Georgi"}]
            got: [{:id=>1, :name=>"Georgi"}, {:id=>2, :name=>"Sasho"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>1, :name=>"Georgi"}]
       +[{:id=>1, :name=>"Georgi"}, {:id=>2, :name=>"Sasho"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1e3ilh7/spec.rb:239
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:212:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  21) ArrayStore behaves like a data store #delete can delete multiple records with a single query
     Failure/Error: expect(store.find({})).to eq [gosho]
       
       expected: [{:id=>3, :name=>"Gosho"}]
            got: []
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>3, :name=>"Gosho"}]
       +[]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1e3ilh7/spec.rb:239
     # /tmp/d20161202-15620-1e3ilh7/spec.rb:229:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.02371 seconds
25 examples, 21 failures

Failed examples:

rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:12 # DataModel creates attribute accessors
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:21 # DataModel has attributes and data_model getters
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:27 # DataModel accepts attributes when initializing
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:39 # DataModel has #find_by_<attribute> methods
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:48 # DataModel id generation creates id on first save and does not change it
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:62 # DataModel id generation does not reuse ids
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:74 # DataModel id generation does not break when there are two models with the same store
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:92 # DataModel equality comparison compares by id if both records are saved
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:108 # DataModel equality comparison uses #equal? if there are no ids
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:124 # DataModel.where finds records by attributes
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:129 # DataModel.where finds records by multiple attributes
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:138 # DataModel.where returns empty collection when nothing is found
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:142 # DataModel.where raises an error if the query is by an unknown key
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:151 # DataModel#delete deletes only the record for which it is called
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:162 # DataModel#delete raises an error if the record is not saved
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:183 # HashStore behaves like a data store #find can find elements by attributes
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:204 # HashStore behaves like a data store #update only updates records with the correct IDs
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:218 # HashStore behaves like a data store #delete can delete multiple records with a single query
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:183 # ArrayStore behaves like a data store #find can find elements by attributes
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:204 # ArrayStore behaves like a data store #update only updates records with the correct IDs
rspec /tmp/d20161202-15620-1e3ilh7/spec.rb:218 # ArrayStore behaves like a data store #delete can delete multiple records with a single query

История (1 версия и 0 коментара)

Емине обнови решението на 01.12.2016 21:58 (преди над 7 години)

+class DataModel
+ attr_accessor :id
+
+ def initialize
+ @id = nil
+ end
+
+ def save
+
+ end
+
+ def delete
+
+ end
+
+ def self.attributes
+
+ end
+
+ def self.data_store
+
+ end
+end
+
+module DataStore
+ class << self
+ def update_record(record, attrs)
+ attrs.each do |attr_key, attr_value|
+ record[attr_key] = attr_value
+ end
+ end
+
+ def suitable_record?(record, query)
+ is_contained = query.select do |attr_key, attr_value|
+ (record.key? attr_key) && (record[attr_key] == attr_value)
+ end
+ is_contained.all?
+ end
+ end
+end
+
+class ArrayStore
+ attr_reader :storage
+
+ def initialize
+ @storage = []
+ end
+
+ def create(record)
+ @storage << record
+ end
+
+ def find(query)
+ result = []
+ @storage.each do |record|
+ result << record if DataStore.suitable_record? record, query
+ end
+ result
+ end
+
+ def update(id, attrs)
+ @storage.each do |record|
+ DataStore.update_record(record, attrs) if record[:id] == id
+ end
+ end
+
+ def delete(query)
+ @storage.delete_if do |record|
+ DataStore.suitable_record? record, query
+ end
+ end
+end
+
+class HashStore
+ attr_reader :storage
+
+ def initialize
+ @storage = {}
+ end
+
+ def create(record)
+ @storage[record[:id]] = record
+ end
+
+ def find(query)
+ result = []
+ @storage.each do |_, record|
+ result << record if DataStore.suitable_record? record, query
+ end
+ result
+ end
+
+ def update(id, attrs)
+ DataStore.update_record(@storage[id], attrs)
+ end
+
+ def delete(query)
+ @storage.delete_if do |_, record|
+ DataStore.suitable_record? record, query
+ end
+ end
+end