mack-data_mapper 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. data/lib/gems/addressable-2.0.0/lib/addressable/idna.rb +4867 -0
  2. data/lib/gems/addressable-2.0.0/lib/addressable/uri.rb +2469 -0
  3. data/lib/gems/addressable-2.0.0/lib/addressable/version.rb +35 -0
  4. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/adapters/data_objects_adapter.rb +85 -0
  5. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/aggregate_functions.rb +201 -0
  6. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/collection.rb +11 -0
  7. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/model.rb +11 -0
  8. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/repository.rb +7 -0
  9. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/support/symbol.rb +21 -0
  10. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/version.rb +7 -0
  11. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates.rb +15 -0
  12. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/abstract_adapter.rb +209 -0
  13. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/data_objects_adapter.rb +709 -0
  14. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
  15. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/mysql_adapter.rb +136 -0
  16. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/postgres_adapter.rb +188 -0
  17. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
  18. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters.rb +22 -0
  19. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_many.rb +147 -0
  20. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_one.rb +107 -0
  21. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb +318 -0
  22. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_one.rb +61 -0
  23. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship.rb +223 -0
  24. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship_chain.rb +81 -0
  25. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations.rb +200 -0
  26. data/lib/gems/dm-core-0.9.7/lib/dm-core/auto_migrations.rb +105 -0
  27. data/lib/gems/dm-core-0.9.7/lib/dm-core/collection.rb +642 -0
  28. data/lib/gems/dm-core-0.9.7/lib/dm-core/dependency_queue.rb +32 -0
  29. data/lib/gems/dm-core-0.9.7/lib/dm-core/hook.rb +11 -0
  30. data/lib/gems/dm-core-0.9.7/lib/dm-core/identity_map.rb +42 -0
  31. data/lib/gems/dm-core-0.9.7/lib/dm-core/is.rb +16 -0
  32. data/lib/gems/dm-core-0.9.7/lib/dm-core/logger.rb +232 -0
  33. data/lib/gems/dm-core-0.9.7/lib/dm-core/migrations/destructive_migrations.rb +17 -0
  34. data/lib/gems/dm-core-0.9.7/lib/dm-core/migrator.rb +29 -0
  35. data/lib/gems/dm-core-0.9.7/lib/dm-core/model.rb +488 -0
  36. data/lib/gems/dm-core-0.9.7/lib/dm-core/naming_conventions.rb +84 -0
  37. data/lib/gems/dm-core-0.9.7/lib/dm-core/property.rb +663 -0
  38. data/lib/gems/dm-core-0.9.7/lib/dm-core/property_set.rb +169 -0
  39. data/lib/gems/dm-core-0.9.7/lib/dm-core/query.rb +628 -0
  40. data/lib/gems/dm-core-0.9.7/lib/dm-core/repository.rb +159 -0
  41. data/lib/gems/dm-core-0.9.7/lib/dm-core/resource.rb +637 -0
  42. data/lib/gems/dm-core-0.9.7/lib/dm-core/scope.rb +58 -0
  43. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/array.rb +13 -0
  44. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/assertions.rb +8 -0
  45. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/errors.rb +23 -0
  46. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/kernel.rb +11 -0
  47. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/symbol.rb +41 -0
  48. data/lib/gems/dm-core-0.9.7/lib/dm-core/support.rb +7 -0
  49. data/lib/gems/dm-core-0.9.7/lib/dm-core/transaction.rb +267 -0
  50. data/lib/gems/dm-core-0.9.7/lib/dm-core/type.rb +160 -0
  51. data/lib/gems/dm-core-0.9.7/lib/dm-core/type_map.rb +80 -0
  52. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/boolean.rb +7 -0
  53. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/discriminator.rb +34 -0
  54. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/object.rb +24 -0
  55. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_boolean.rb +34 -0
  56. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_datetime.rb +33 -0
  57. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/serial.rb +9 -0
  58. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/text.rb +10 -0
  59. data/lib/gems/dm-core-0.9.7/lib/dm-core/types.rb +19 -0
  60. data/lib/gems/dm-core-0.9.7/lib/dm-core/version.rb +3 -0
  61. data/lib/gems/dm-core-0.9.7/lib/dm-core.rb +217 -0
  62. data/lib/gems/dm-core-0.9.7/script/all +5 -0
  63. data/lib/gems/dm-core-0.9.7/script/performance.rb +284 -0
  64. data/lib/gems/dm-core-0.9.7/script/profile.rb +87 -0
  65. data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations/version.rb +5 -0
  66. data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations.rb +1 -0
  67. data/lib/gems/dm-migrations-0.9.7/lib/migration.rb +215 -0
  68. data/lib/gems/dm-migrations-0.9.7/lib/migration_runner.rb +88 -0
  69. data/lib/gems/dm-migrations-0.9.7/lib/spec/example/migration_example_group.rb +73 -0
  70. data/lib/gems/dm-migrations-0.9.7/lib/spec/matchers/migration_matchers.rb +107 -0
  71. data/lib/gems/dm-migrations-0.9.7/lib/sql/column.rb +9 -0
  72. data/lib/gems/dm-migrations-0.9.7/lib/sql/mysql.rb +52 -0
  73. data/lib/gems/dm-migrations-0.9.7/lib/sql/postgresql.rb +78 -0
  74. data/lib/gems/dm-migrations-0.9.7/lib/sql/sqlite3.rb +43 -0
  75. data/lib/gems/dm-migrations-0.9.7/lib/sql/table.rb +19 -0
  76. data/lib/gems/dm-migrations-0.9.7/lib/sql/table_creator.rb +81 -0
  77. data/lib/gems/dm-migrations-0.9.7/lib/sql/table_modifier.rb +53 -0
  78. data/lib/gems/dm-migrations-0.9.7/lib/sql.rb +10 -0
  79. data/lib/gems/dm-observer-0.9.7/lib/dm-observer/version.rb +5 -0
  80. data/lib/gems/dm-observer-0.9.7/lib/dm-observer.rb +91 -0
  81. data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer/version.rb +5 -0
  82. data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer.rb +183 -0
  83. data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps/version.rb +5 -0
  84. data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps.rb +57 -0
  85. data/lib/gems/dm-types-0.9.7/lib/dm-types/bcrypt_hash.rb +31 -0
  86. data/lib/gems/dm-types-0.9.7/lib/dm-types/csv.rb +28 -0
  87. data/lib/gems/dm-types-0.9.7/lib/dm-types/enum.rb +70 -0
  88. data/lib/gems/dm-types-0.9.7/lib/dm-types/epoch_time.rb +27 -0
  89. data/lib/gems/dm-types-0.9.7/lib/dm-types/file_path.rb +27 -0
  90. data/lib/gems/dm-types-0.9.7/lib/dm-types/flag.rb +61 -0
  91. data/lib/gems/dm-types-0.9.7/lib/dm-types/ip_address.rb +30 -0
  92. data/lib/gems/dm-types-0.9.7/lib/dm-types/json.rb +40 -0
  93. data/lib/gems/dm-types-0.9.7/lib/dm-types/regexp.rb +20 -0
  94. data/lib/gems/dm-types-0.9.7/lib/dm-types/serial.rb +8 -0
  95. data/lib/gems/dm-types-0.9.7/lib/dm-types/slug.rb +37 -0
  96. data/lib/gems/dm-types-0.9.7/lib/dm-types/uri.rb +29 -0
  97. data/lib/gems/dm-types-0.9.7/lib/dm-types/uuid.rb +64 -0
  98. data/lib/gems/dm-types-0.9.7/lib/dm-types/version.rb +5 -0
  99. data/lib/gems/dm-types-0.9.7/lib/dm-types/yaml.rb +36 -0
  100. data/lib/gems/dm-types-0.9.7/lib/dm-types.rb +28 -0
  101. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/absent_field_validator.rb +60 -0
  102. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/acceptance_validator.rb +76 -0
  103. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/auto_validate.rb +153 -0
  104. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/block_validator.rb +60 -0
  105. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/confirmation_validator.rb +80 -0
  106. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/contextual_validators.rb +56 -0
  107. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/custom_validator.rb +72 -0
  108. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/format_validator.rb +97 -0
  109. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/email.rb +40 -0
  110. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/url.rb +20 -0
  111. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/generic_validator.rb +100 -0
  112. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/length_validator.rb +113 -0
  113. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/method_validator.rb +68 -0
  114. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/numeric_validator.rb +83 -0
  115. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/primitive_validator.rb +60 -0
  116. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/required_field_validator.rb +88 -0
  117. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/support/object.rb +5 -0
  118. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/uniqueness_validator.rb +64 -0
  119. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/validation_errors.rb +63 -0
  120. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/version.rb +5 -0
  121. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/within_validator.rb +53 -0
  122. data/lib/gems/dm-validations-0.9.7/lib/dm-validations.rb +234 -0
  123. data/lib/gems/json_pure-1.1.3/GPL +340 -0
  124. data/lib/gems/json_pure-1.1.3/VERSION +1 -0
  125. data/lib/gems/json_pure-1.1.3/bin/edit_json.rb +10 -0
  126. data/lib/gems/json_pure-1.1.3/bin/prettify_json.rb +76 -0
  127. data/lib/gems/json_pure-1.1.3/lib/json/Array.xpm +21 -0
  128. data/lib/gems/json_pure-1.1.3/lib/json/FalseClass.xpm +21 -0
  129. data/lib/gems/json_pure-1.1.3/lib/json/Hash.xpm +21 -0
  130. data/lib/gems/json_pure-1.1.3/lib/json/Key.xpm +73 -0
  131. data/lib/gems/json_pure-1.1.3/lib/json/NilClass.xpm +21 -0
  132. data/lib/gems/json_pure-1.1.3/lib/json/Numeric.xpm +28 -0
  133. data/lib/gems/json_pure-1.1.3/lib/json/String.xpm +96 -0
  134. data/lib/gems/json_pure-1.1.3/lib/json/TrueClass.xpm +21 -0
  135. data/lib/gems/json_pure-1.1.3/lib/json/add/core.rb +135 -0
  136. data/lib/gems/json_pure-1.1.3/lib/json/add/rails.rb +58 -0
  137. data/lib/gems/json_pure-1.1.3/lib/json/common.rb +354 -0
  138. data/lib/gems/json_pure-1.1.3/lib/json/editor.rb +1362 -0
  139. data/lib/gems/json_pure-1.1.3/lib/json/ext.rb +13 -0
  140. data/lib/gems/json_pure-1.1.3/lib/json/json.xpm +1499 -0
  141. data/lib/gems/json_pure-1.1.3/lib/json/pure/generator.rb +394 -0
  142. data/lib/gems/json_pure-1.1.3/lib/json/pure/parser.rb +259 -0
  143. data/lib/gems/json_pure-1.1.3/lib/json/pure.rb +75 -0
  144. data/lib/gems/json_pure-1.1.3/lib/json/version.rb +9 -0
  145. data/lib/gems/json_pure-1.1.3/lib/json.rb +235 -0
  146. data/lib/gems/launchy-0.3.2/bin/launchy +12 -0
  147. data/lib/gems/launchy-0.3.2/lib/launchy/application.rb +163 -0
  148. data/lib/gems/launchy-0.3.2/lib/launchy/browser.rb +85 -0
  149. data/lib/gems/launchy-0.3.2/lib/launchy/command_line.rb +48 -0
  150. data/lib/gems/launchy-0.3.2/lib/launchy/gemspec.rb +53 -0
  151. data/lib/gems/launchy-0.3.2/lib/launchy/specification.rb +133 -0
  152. data/lib/gems/launchy-0.3.2/lib/launchy/version.rb +18 -0
  153. data/lib/gems/launchy-0.3.2/lib/launchy.rb +58 -0
  154. data/lib/gems/uuidtools-1.0.3/lib/uuidtools/version.rb +32 -0
  155. data/lib/gems/uuidtools-1.0.3/lib/uuidtools.rb +648 -0
  156. data/lib/gems.rb +13 -0
  157. data/lib/mack-data_mapper/migration_generator/migration_generator.rb +5 -0
  158. data/lib/mack-data_mapper/migration_generator/templates/db/migrations/%=@migration_name%.rb.template +1 -1
  159. data/lib/mack-data_mapper/model_generator/manifest.yml +3 -3
  160. data/lib/mack-data_mapper/model_generator/model_generator.rb +8 -1
  161. data/lib/mack-data_mapper/model_generator/templates/model.rb.template +1 -1
  162. data/lib/mack-data_mapper/model_generator/templates/rspec.rb.template +1 -1
  163. data/lib/mack-data_mapper/model_generator/templates/test_case.rb.template +1 -1
  164. data/lib/mack-data_mapper.rb +3 -2
  165. data/lib/mack-data_mapper_tasks.rb +7 -0
  166. metadata +235 -86
@@ -0,0 +1,68 @@
1
+ module DataMapper
2
+ module Validate
3
+
4
+ ##
5
+ #
6
+ # @author Guy van den Berg
7
+ # @since 0.9
8
+ class MethodValidator < GenericValidator
9
+
10
+ def initialize(field_name, options={})
11
+ super
12
+ @field_name, @options = field_name, options.clone
13
+ @options[:method] = @field_name unless @options.has_key?(:method)
14
+ end
15
+
16
+ def call(target)
17
+ result,message = target.send(@options[:method])
18
+ add_error(target,message,@field_name) if !result
19
+ result
20
+ end
21
+
22
+ def ==(other)
23
+ @options[:method] == other.instance_variable_get(:@options)[:method] && super
24
+ end
25
+ end # class MethodValidator
26
+
27
+ module ValidatesWithMethod
28
+
29
+ ##
30
+ # Validate using the given method. The method given needs to return:
31
+ # [result::<Boolean>, Error Message::<String>]
32
+ #
33
+ # @example [Usage]
34
+ # require 'dm-validations'
35
+ #
36
+ # class Page
37
+ # include DataMapper::Resource
38
+ #
39
+ # property :zip_code, String
40
+ #
41
+ # validates_with_method :in_the_right_location?
42
+ #
43
+ # def in_the_right_location?
44
+ # if @zip_code == "94301"
45
+ # return true
46
+ # else
47
+ # return [false, "You're in the wrong zip code"]
48
+ # end
49
+ # end
50
+ #
51
+ # # A call to valid? will return false and
52
+ # # populate the object's errors with "You're in the
53
+ # # wrong zip code" unless zip_code == "94301"
54
+ #
55
+ # # You can also specify field:
56
+ #
57
+ # validates_with_method :zip_code, :in_the_right_location?
58
+ #
59
+ # # it will add returned error message to :zip_code field
60
+ #
61
+ def validates_with_method(*fields)
62
+ opts = opts_from_validator_args(fields)
63
+ add_validator_to_context(opts, fields, DataMapper::Validate::MethodValidator)
64
+ end
65
+
66
+ end # module ValidatesWithMethod
67
+ end # module Validate
68
+ end # module DataMapper
@@ -0,0 +1,83 @@
1
+ module DataMapper
2
+ module Validate
3
+
4
+ ##
5
+ #
6
+ # @author Guy van den Berg
7
+ # @since 0.9
8
+ class NumericValidator < GenericValidator
9
+
10
+ def initialize(field_name, options={})
11
+ super
12
+ @field_name, @options = field_name, options
13
+ @options[:integer_only] = false unless @options.has_key?(:integer_only)
14
+ end
15
+
16
+ def call(target)
17
+ value = target.send(field_name)
18
+ return true if @options[:allow_nil] && value.nil?
19
+
20
+ value = value.kind_of?(BigDecimal) ? value.to_s('F') : value.to_s
21
+
22
+ error_message = @options[:message]
23
+ precision = @options[:precision]
24
+ scale = @options[:scale]
25
+
26
+ if @options[:integer_only]
27
+ return true if value =~ /\A[+-]?\d+\z/
28
+ error_message ||= '%s must be an integer'.t(Extlib::Inflection.humanize(@field_name))
29
+ else
30
+ # FIXME: if precision and scale are not specified, can we assume that it is an integer?
31
+ # probably not, as floating point numbers don't have hard
32
+ # defined scale. the scale floats with the length of the
33
+ # integral and precision. Ie. if precision = 10 and integral
34
+ # portion of the number is 9834 (4 digits), the max scale will
35
+ # be 6 (10 - 4). But if the integral length is 1, max scale
36
+ # will be (10 - 1) = 9, so 1.234567890.
37
+ # In MySQL somehow you can hard-define scale on floats. Not
38
+ # quite sure how that works...
39
+ if precision && scale
40
+ #handles both Float when it has scale specified and BigDecimal
41
+ if precision > scale && scale > 0
42
+ return true if value =~ /\A[+-]?(?:\d{1,#{precision - scale}}|\d{0,#{precision - scale}}\.\d{1,#{scale}})\z/
43
+ elsif precision > scale && scale == 0
44
+ return true if value =~ /\A[+-]?(?:\d{1,#{precision}}(?:\.0)?)\z/
45
+ elsif precision == scale
46
+ return true if value =~ /\A[+-]?(?:0(?:\.\d{1,#{scale}})?)\z/
47
+ else
48
+ raise ArgumentError, "Invalid precision #{precision.inspect} and scale #{scale.inspect} for #{field_name} (value: #{value.inspect} #{value.class})"
49
+ end
50
+ elsif precision && scale.nil?
51
+ # for floats, if scale is not set
52
+
53
+ #total number of digits is less or equal precision
54
+ return true if value.gsub(/[^\d]/,'').length <= precision
55
+
56
+ #number of digits before decimal == precision, and the number is x.0. same as scale = 0
57
+ return true if value =~ /\A[+-]?(?:\d{1,#{precision}}(?:\.0)?)\z/
58
+ else
59
+ return true if value =~ /\A[+-]?(?:\d+|\d*\.\d+)\z/
60
+ end
61
+ error_message ||= '%s must be a number'.t(Extlib::Inflection.humanize(@field_name))
62
+ end
63
+
64
+ add_error(target, error_message, @field_name)
65
+
66
+ # TODO: check the gt, gte, lt, lte, and eq options
67
+
68
+ return false
69
+ end
70
+ end # class NumericValidator
71
+
72
+ module ValidatesIsNumber
73
+
74
+ # Validate whether a field is numeric
75
+ #
76
+ def validates_is_number(*fields)
77
+ opts = opts_from_validator_args(fields)
78
+ add_validator_to_context(opts, fields, DataMapper::Validate::NumericValidator)
79
+ end
80
+
81
+ end # module ValidatesIsNumber
82
+ end # module Validate
83
+ end # module DataMapper
@@ -0,0 +1,60 @@
1
+ module DataMapper
2
+ module Validate
3
+
4
+ ##
5
+ #
6
+ # @author Dirkjan Bussink
7
+ # @since 0.9
8
+ class PrimitiveValidator < GenericValidator
9
+
10
+ def initialize(field_name, options={})
11
+ super
12
+ @field_name, @options = field_name, options
13
+ end
14
+
15
+ def call(target)
16
+ value = target.validation_property_value(@field_name)
17
+ property = target.validation_property(@field_name)
18
+ return true if value.nil? || value.kind_of?(property.primitive) || property.primitive == TrueClass && value.kind_of?(FalseClass)
19
+
20
+ error_message = @options[:message] || default_error(property)
21
+ add_error(target, error_message, @field_name)
22
+
23
+ false
24
+ end
25
+
26
+ protected
27
+
28
+ def default_error(property)
29
+ "%s must be of type %s".t(Extlib::Inflection.humanize(@field_name), property.primitive)
30
+ end
31
+
32
+ end # class PrimitiveValidator
33
+
34
+ module ValidatesIsPrimitive
35
+
36
+ ##
37
+ # Validates that the specified attribute is of the correct primitive type.
38
+ #
39
+ # @example [Usage]
40
+ # require 'dm-validations'
41
+ #
42
+ # class Person
43
+ # include DataMapper::Resource
44
+ #
45
+ # property :birth_date, Date
46
+ #
47
+ # validates_is_primitive :birth_date
48
+ #
49
+ # # a call to valid? will return false unless
50
+ # # the birth_date is something that can be properly
51
+ # # casted into a Date object.
52
+ # end
53
+ def validates_is_primitive(*fields)
54
+ opts = opts_from_validator_args(fields)
55
+ add_validator_to_context(opts, fields, DataMapper::Validate::PrimitiveValidator)
56
+ end
57
+
58
+ end # module ValidatesPresent
59
+ end # module Validate
60
+ end # module DataMapper
@@ -0,0 +1,88 @@
1
+ module DataMapper
2
+ module Validate
3
+
4
+ ##
5
+ #
6
+ # @author Guy van den Berg
7
+ # @since 0.9
8
+ class RequiredFieldValidator < GenericValidator
9
+
10
+ def initialize(field_name, options={})
11
+ super
12
+ @field_name, @options = field_name, options
13
+ end
14
+
15
+ def call(target)
16
+ value = target.validation_property_value(@field_name)
17
+ property = target.validation_property(@field_name)
18
+ return true if present?(value, property)
19
+
20
+ error_message = @options[:message] || default_error(property)
21
+ add_error(target, error_message, @field_name)
22
+
23
+ false
24
+ end
25
+
26
+ protected
27
+
28
+ # Boolean property types are considered present if non-nil.
29
+ # Other property types are considered present if non-blank.
30
+ # Non-properties are considered present if non-blank.
31
+ def present?(value, property)
32
+ boolean_type?(property) ? !value.nil? : !value.blank?
33
+ end
34
+
35
+ def default_error(property)
36
+ actual = boolean_type?(property) ? "nil".t : "blank".t
37
+ "%s must not be %s".t(Extlib::Inflection.humanize(@field_name), actual)
38
+ end
39
+
40
+ # Is +property+ a boolean property?
41
+ #
42
+ # Returns true for Boolean, ParanoidBoolean, TrueClass, etc. properties.
43
+ # Returns false for other property types.
44
+ # Returns false for non-properties.
45
+ def boolean_type?(property)
46
+ property ? property.primitive == TrueClass : false
47
+ end
48
+
49
+ end # class RequiredFieldValidator
50
+
51
+ module ValidatesPresent
52
+
53
+ ##
54
+ # Validates that the specified attribute is present.
55
+ #
56
+ # For most property types "being present" is the same as being "not
57
+ # blank" as determined by the attribute's #blank? method. However, in
58
+ # the case of Boolean, "being present" means not nil; i.e. true or
59
+ # false.
60
+ #
61
+ # @note
62
+ # dm-core's support lib adds the blank? method to many classes,
63
+ # @see lib/dm-core/support/blank.rb (dm-core) for more information.
64
+ #
65
+ # @example [Usage]
66
+ # require 'dm-validations'
67
+ #
68
+ # class Page
69
+ # include DataMapper::Resource
70
+ #
71
+ # property :required_attribute, String
72
+ # property :another_required, String
73
+ # property :yet_again, String
74
+ #
75
+ # validates_present :required_attribute
76
+ # validates_present :another_required, :yet_again
77
+ #
78
+ # # a call to valid? will return false unless
79
+ # # all three attributes are !blank?
80
+ # end
81
+ def validates_present(*fields)
82
+ opts = opts_from_validator_args(fields)
83
+ add_validator_to_context(opts, fields, DataMapper::Validate::RequiredFieldValidator)
84
+ end
85
+
86
+ end # module ValidatesPresent
87
+ end # module Validate
88
+ end # module DataMapper
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def validatable?
3
+ false
4
+ end
5
+ end
@@ -0,0 +1,64 @@
1
+ module DataMapper
2
+ module Validate
3
+
4
+ ##
5
+ #
6
+ # @author Guy van den Berg
7
+ # @since 0.9
8
+ class UniquenessValidator < GenericValidator
9
+ include Assertions
10
+
11
+ def initialize(field_name, options = {})
12
+ assert_kind_of 'scope', options[:scope], Array, Symbol if options.has_key?(:scope)
13
+ super
14
+ @field_name, @options = field_name, options
15
+ end
16
+
17
+ def call(target)
18
+ scope = Array(@options[:scope])
19
+
20
+ return true if @options[:allow_nil] && target.send(field_name).nil?
21
+
22
+ repository_name = target.repository.name
23
+
24
+ opts = {
25
+ :fields => target.model.key,
26
+ field_name => target.validation_property_value(field_name)
27
+ }
28
+
29
+ scope.each do |item|
30
+ if target.model.properties(repository_name).has_property?(item)
31
+ opts[item] = target.validation_property_value(item)
32
+ elsif target.model.relationships(repository_name).has_key?(item)
33
+ target.validation_association_keys(item).each do |key|
34
+ opts[key] = target.validation_property_value(key)
35
+ end
36
+ end
37
+ end
38
+
39
+ resource = repository(repository_name) { target.model.first(opts) }
40
+
41
+ return true if resource.nil?
42
+
43
+ # is target and found resource identic? same instance... but not ==
44
+ return true if !target.new_record? && resource.repository.name == repository_name && resource.model == target.model && resource.key == target.key
45
+
46
+ error_message = @options[:message] || "%s is already taken".t(Extlib::Inflection.humanize(field_name))
47
+ add_error(target, error_message , field_name)
48
+
49
+ return false
50
+ end
51
+ end # class UniquenessValidator
52
+
53
+ module ValidatesIsUnique
54
+
55
+ # Validate the uniqueness of a field
56
+ #
57
+ def validates_is_unique(*fields)
58
+ opts = opts_from_validator_args(fields)
59
+ add_validator_to_context(opts, fields, DataMapper::Validate::UniquenessValidator)
60
+ end
61
+
62
+ end # module ValidatesIsUnique
63
+ end # module Validate
64
+ end # module DataMapper
@@ -0,0 +1,63 @@
1
+ module DataMapper
2
+ module Validate
3
+
4
+ ##
5
+ #
6
+ # @author Guy van den Berg
7
+ # @since 0.9
8
+ class ValidationErrors
9
+
10
+ include Enumerable
11
+
12
+ # Clear existing validation errors.
13
+ def clear!
14
+ errors.clear
15
+ end
16
+
17
+ # Add a validation error. Use the field_name :general if the errors does
18
+ # not apply to a specific field of the Resource.
19
+ #
20
+ # @param <Symbol> field_name the name of the field that caused the error
21
+ # @param <String> message the message to add
22
+ def add(field_name, message)
23
+ (errors[field_name] ||= []) << message
24
+ end
25
+
26
+ # Collect all errors into a single list.
27
+ def full_messages
28
+ errors.inject([]) do |list,pair|
29
+ list += pair.last
30
+ end
31
+ end
32
+
33
+ # Return validation errors for a particular field_name.
34
+ #
35
+ # @param <Symbol> field_name the name of the field you want an error for
36
+ def on(field_name)
37
+ errors_for_field = errors[field_name]
38
+ errors_for_field.blank? ? nil : errors_for_field
39
+ end
40
+
41
+ def each
42
+ errors.map.each do |k,v|
43
+ next if v.blank?
44
+ yield(v)
45
+ end
46
+ end
47
+
48
+ def empty?
49
+ entries.empty?
50
+ end
51
+
52
+ def method_missing(meth, *args, &block)
53
+ errors.send(meth, *args, &block)
54
+ end
55
+
56
+ private
57
+ def errors
58
+ @errors ||= {}
59
+ end
60
+
61
+ end # class ValidationErrors
62
+ end # module Validate
63
+ end # module DataMapper
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Validations
3
+ VERSION = "0.9.7"
4
+ end
5
+ end
@@ -0,0 +1,53 @@
1
+ module DataMapper
2
+ module Validate
3
+
4
+ ##
5
+ #
6
+ # @author Guy van den Berg
7
+ # @since 0.9
8
+ class WithinValidator < GenericValidator
9
+
10
+ def initialize(field_name, options={})
11
+ super
12
+ @field_name, @options = field_name, options
13
+ @options[:set] = [] unless @options.has_key?(:set)
14
+ end
15
+
16
+ def call(target)
17
+ includes = @options[:set].include?(target.send(field_name))
18
+ return true if includes
19
+
20
+ field_name = Extlib::Inflection.humanize(@field_name)
21
+ if @options[:set].is_a?(Range)
22
+ if @options[:set].first != -n && @options[:set].last != n
23
+ error_message = @options[:message] || "%s must be between %s and %s".t(field_name, @options[:set].first, @options[:set].last)
24
+ elsif @options[:set].first == -n
25
+ error_message = @options[:message] || "%s must be less than %s".t(field_name, @options[:set].last)
26
+ elsif @options[:set].last == n
27
+ error_message = @options[:message] || "%s must be greater than %s".t(field_name, @options[:set].first)
28
+ end
29
+ else
30
+ error_message = "%s must be one of [%s]".t(field_name, @options[:set].join(', '))
31
+ end
32
+
33
+ add_error(target, error_message , @field_name)
34
+ return false
35
+ end
36
+
37
+ def n
38
+ 1.0/0
39
+ end
40
+ end # class WithinValidator
41
+
42
+ module ValidatesWithin
43
+
44
+ # Validate the absence of a field
45
+ #
46
+ def validates_within(*fields)
47
+ opts = opts_from_validator_args(fields)
48
+ add_validator_to_context(opts, fields, DataMapper::Validate::WithinValidator)
49
+ end
50
+
51
+ end # module ValidatesWithin
52
+ end # module Validate
53
+ end # module DataMapper