Даниела обнови решението на 01.12.2016 22:10 (преди около 8 години)
+module ClassMethods
+ attr_accessor :attributes_array
+ attr_accessor :storage
+ def attributes(*columns)
+ if !columns.empty?
+ create_find_by(columns.to_a)
+ DataModel.attributes_array = columns.to_a
+ else
+ DataModel.attributes_array
+ end
+ end
+
+ def data_store(storage = nil)
+ if storage != nil
+ DataModel.storage = storage
+ else
+ DataModel.storage
+ end
+ end
+
+ def where(query)
+ query.each do |k, _|
+ raise DataModel::UnknownAttributeError, 'Unknown attribute :' + k
+ .to_s unless DataModel.attributes_array.include?(k)
+ end
+ result = []
+ DataModel.storage.find(query).each do |n|
+ result << self.new(n)
+ result.last.id = n[:id]
+ end
+ result
+ end
+
+ def create_find_by(attributes)
+ attributes.each do |x|
+ self.class.send :define_method, "find_by_" + x.to_s do |value|
+ result = []
+ DataModel.storage.find(x.to_s.to_sym => value).each do |n|
+ result << self.new(n)
+ result.last.id = n[:id]
+ end
+ result
+ end
+ end
+ end
+end
+
+class DataModel
+ class DeleteUnsavedRecordError < StandardError
+ end
+
+ class UnknownAttributeError < StandardError
+ end
+
+ extend ClassMethods
+
+ @id
+ attr_accessor :id
+
+ def initialize(values = {})
+ DataModel.attributes_array.each do |x|
+ singleton_class.class_eval { attr_accessor x.to_s }
+ send(x.to_s + '=', nil)
+ end
+ values.each do |k, v|
+ send(k.to_s + '=', v) if DataModel.attributes_array.include?(k)
+ end
+ end
+
+ def save
+ if @id == nil
+ @id = DataModel.storage.max_id += 1
+ hash_attributes = Hash[DataModel
+ .attributes_array.each.map { |k| [k, send(k.to_s)] }].merge!(id: @id)
+ DataModel.storage.create(hash_attributes)
+ else
+ hash_attributes = Hash[DataModel
+ .attributes_array.each.map { |k| [k, send(k.to_s)] }].merge!(id: @id)
+ DataModel.storage.update(@id, hash_attributes)
+ end
+ end
+
+ def delete
+ if !DataModel.storage.find(id: @id).empty?
+ DataModel.storage.delete({id: @id})
+ else
+ raise DataModel::DeleteUnsavedRecordError
+ end
+ end
+
+ def ==(other)
+ if !(other.class == self.class)
+ false
+ elsif !DataModel.storage.find(id: @id).empty? && !DataModel
+ .storage.find(id: other.id).empty? && (@id == other.id)
+ true
+ elsif self.object_id == other.object_id
+ true
+ end
+ end
+end
+
+class ArrayStore
+ def initialize
+ @storage = []
+ @max_id = 0
+ end
+
+ def create(record)
+ @storage << record
+ end
+
+ def find(query)
+ @storage.select { |n| n.merge(query) == n }
+ end
+
+ def update(id, attributes)
+ idx = 0
+ @storage.each_with_index do |n, index|
+ idx = index if n[:id] == id
+ end
+ attributes.each do |k, v|
+ @storage[idx][k] = v if @storage[idx].key?(k)
+ end
+ end
+
+ def delete(query)
+ @storage.delete_if { |n| n.merge(query) == n }
+ end
+
+ attr_reader :storage
+ attr_accessor :max_id
+end
+
+class HashStore
+ def initialize
+ @storage = {}
+ @max_id = 0
+ end
+
+ def create(record)
+ @storage[record[:id]] = record
+ end
+
+ def find(query)
+ @storage.select { |_, v| v.merge(query) == v }.values
+ end
+
+ def update(id, attributes)
+ attributes.each do |k, v|
+ @storage[id][k] = v if @storage[id].key?(k)
+ end
+ end
+
+ def delete(query)
+ @storage.delete_if { |_, v| v.merge(query) == v }
+ end
+
+ attr_reader :storage
+ attr_accessor :max_id
+end