| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | require "providers/provider_factory" | 
					
						
							|  |  |  | require "db/exceptions/invalid_record" | 
					
						
							|  |  |  | require "json" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MongoModel | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def to_json | 
					
						
							|  |  |  |     JSON.pretty_generate self.to_hash | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def to_hash | 
					
						
							|  |  |  |     h = to_hash_without_id | 
					
						
							|  |  |  |     h["id"] = self.id | 
					
						
							|  |  |  |     h | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def to_mongo_hash | 
					
						
							|  |  |  |     h = to_hash_without_id | 
					
						
							|  |  |  |     h["_id"] = self.id | 
					
						
							|  |  |  |     h | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def is_empty? val | 
					
						
							|  |  |  |     val.nil? or val.strip.empty? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def check_string! val | 
					
						
							|  |  |  |     raise ArgumentError unless val.is_a?(String) | 
					
						
							|  |  |  |     val.strip! | 
					
						
							|  |  |  |     raise ArgumentError if val.empty? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def check_array! val, type, empty=false | 
					
						
							|  |  |  |     raise ArgumentError unless val.is_a?(Array) | 
					
						
							|  |  |  |     raise ArgumentError if !empty and val.empty? | 
					
						
							|  |  |  |     val.each do |v| | 
					
						
							|  |  |  |       raise ArgumentError unless v.is_a?(type) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def check_name_value val | 
					
						
							|  |  |  |     raise ArgumentError.new "Invalid name, it should contains 0-9, a-z, A-Z, _, - symbols only" if val.match(/^[0-9a-zA-Z_\-]+$/).nil? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def check_provider provider=self.provider | 
					
						
							| 
									
										
										
										
											2014-06-18 15:11:47 +04:00
										 |  |  |     unless ::Provider::ProviderFactory.providers.include?(provider) | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |       raise InvalidRecord.new "Invalid provider '#{provider}'" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  |   def validate! | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       self.validate_fields_types | 
					
						
							|  |  |  |       self.class.validate_model(self) | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |     rescue InvalidRecord => e | 
					
						
							|  |  |  |       error_message = self.build_error_message(e.message) | 
					
						
							|  |  |  |       raise InvalidRecord.new(error_message) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def build_error_message(message) | 
					
						
							|  |  |  |     # overrided in descendants | 
					
						
							|  |  |  |     message | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |   # types - Hash | 
					
						
							|  |  |  |   #   key - param name | 
					
						
							|  |  |  |   #   value - Hash | 
					
						
							|  |  |  |   #     :type - param type | 
					
						
							|  |  |  |   #     :empty - can param be empty? (false) | 
					
						
							|  |  |  |   #     :nil - can param be nil? (false) | 
					
						
							|  |  |  |   #     :value_type - type of array element (String) | 
					
						
							|  |  |  |   def self.types types | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  |     define_method :validate_fields_types do | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |       t = types.keys | 
					
						
							|  |  |  |       e = types.keys | 
					
						
							|  |  |  |       n = types.keys | 
					
						
							|  |  |  |       types.each do |name, value| | 
					
						
							|  |  |  |         if value[:nil] | 
					
						
							|  |  |  |           n.delete(name) | 
					
						
							|  |  |  |           if self.send(name).nil? | 
					
						
							|  |  |  |             e.delete(name) | 
					
						
							|  |  |  |             t.delete(name) | 
					
						
							|  |  |  |             next | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           n.delete(name) unless self.send(name).nil? | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         if self.send(name).is_a? value[:type] | 
					
						
							|  |  |  |           t.delete(name) | 
					
						
							|  |  |  |           self.send(name).strip! if value[:type] == String | 
					
						
							|  |  |  |           if value[:type] == Array | 
					
						
							|  |  |  |             unless value[:value_type] == false | 
					
						
							|  |  |  |               type = value[:value_type] || String | 
					
						
							|  |  |  |               self.send(name).each do |e| | 
					
						
							|  |  |  |                 unless e.is_a?(type) | 
					
						
							|  |  |  |                   t.push(name) | 
					
						
							|  |  |  |                   break | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           e.delete(name) if value[:empty] or !self.send(name).empty? | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       raise InvalidRecord.new "Parameter(s) '#{n.join("', '")}' can not be undefined" unless n.empty? | 
					
						
							|  |  |  |       raise InvalidRecord.new "Parameter(s) '#{t.join("', '")}' have invalid type(s)" unless t.empty? | 
					
						
							|  |  |  |       raise InvalidRecord.new "Parameter(s) '#{e.join("', '")}' can not be empty" unless e.empty? | 
					
						
							|  |  |  |       if types.has_key? :provider | 
					
						
							|  |  |  |         self.send("check_provider") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  |   def self.validators | 
					
						
							|  |  |  |     @validators || [] | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # all exceptions are handled in @validate! method | 
					
						
							|  |  |  |   def self.validate_model(model) | 
					
						
							|  |  |  |     validators.each do |validator| | 
					
						
							|  |  |  |       validator.new(model).validate! | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # private class methods | 
					
						
							|  |  |  |   class << self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_validators(*validators_to_add) | 
					
						
							|  |  |  |       @validators ||= [] | 
					
						
							|  |  |  |       @validators += validators_to_add | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def unset_validators(*validators_to_remove) | 
					
						
							|  |  |  |       @validators ||= [] | 
					
						
							|  |  |  |       self.validators -= validators_to_remove | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | end |