ghost_dm-core 1.3.0.beta

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 (254) hide show
  1. data/.autotest +29 -0
  2. data/.document +5 -0
  3. data/.gitignore +35 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +65 -0
  6. data/LICENSE +20 -0
  7. data/README.md +269 -0
  8. data/Rakefile +4 -0
  9. data/dm-core.gemspec +24 -0
  10. data/lib/dm-core.rb +292 -0
  11. data/lib/dm-core/adapters.rb +222 -0
  12. data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
  13. data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
  14. data/lib/dm-core/associations/many_to_many.rb +499 -0
  15. data/lib/dm-core/associations/many_to_one.rb +290 -0
  16. data/lib/dm-core/associations/one_to_many.rb +348 -0
  17. data/lib/dm-core/associations/one_to_one.rb +86 -0
  18. data/lib/dm-core/associations/relationship.rb +663 -0
  19. data/lib/dm-core/backwards.rb +13 -0
  20. data/lib/dm-core/collection.rb +1515 -0
  21. data/lib/dm-core/core_ext/kernel.rb +23 -0
  22. data/lib/dm-core/core_ext/pathname.rb +6 -0
  23. data/lib/dm-core/core_ext/symbol.rb +10 -0
  24. data/lib/dm-core/identity_map.rb +7 -0
  25. data/lib/dm-core/model.rb +874 -0
  26. data/lib/dm-core/model/hook.rb +103 -0
  27. data/lib/dm-core/model/is.rb +32 -0
  28. data/lib/dm-core/model/property.rb +249 -0
  29. data/lib/dm-core/model/relationship.rb +378 -0
  30. data/lib/dm-core/model/scope.rb +89 -0
  31. data/lib/dm-core/property.rb +866 -0
  32. data/lib/dm-core/property/binary.rb +21 -0
  33. data/lib/dm-core/property/boolean.rb +20 -0
  34. data/lib/dm-core/property/class.rb +17 -0
  35. data/lib/dm-core/property/date.rb +10 -0
  36. data/lib/dm-core/property/date_time.rb +10 -0
  37. data/lib/dm-core/property/decimal.rb +36 -0
  38. data/lib/dm-core/property/discriminator.rb +44 -0
  39. data/lib/dm-core/property/float.rb +16 -0
  40. data/lib/dm-core/property/integer.rb +22 -0
  41. data/lib/dm-core/property/invalid_value_error.rb +22 -0
  42. data/lib/dm-core/property/lookup.rb +27 -0
  43. data/lib/dm-core/property/numeric.rb +38 -0
  44. data/lib/dm-core/property/object.rb +34 -0
  45. data/lib/dm-core/property/serial.rb +14 -0
  46. data/lib/dm-core/property/string.rb +38 -0
  47. data/lib/dm-core/property/text.rb +9 -0
  48. data/lib/dm-core/property/time.rb +10 -0
  49. data/lib/dm-core/property_set.rb +177 -0
  50. data/lib/dm-core/query.rb +1366 -0
  51. data/lib/dm-core/query/conditions/comparison.rb +911 -0
  52. data/lib/dm-core/query/conditions/operation.rb +721 -0
  53. data/lib/dm-core/query/direction.rb +36 -0
  54. data/lib/dm-core/query/operator.rb +35 -0
  55. data/lib/dm-core/query/path.rb +114 -0
  56. data/lib/dm-core/query/sort.rb +39 -0
  57. data/lib/dm-core/relationship_set.rb +72 -0
  58. data/lib/dm-core/repository.rb +226 -0
  59. data/lib/dm-core/resource.rb +1214 -0
  60. data/lib/dm-core/resource/persistence_state.rb +75 -0
  61. data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
  62. data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
  63. data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
  64. data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
  65. data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
  66. data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
  67. data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -0
  68. data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
  69. data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
  70. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  71. data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
  72. data/lib/dm-core/spec/setup.rb +174 -0
  73. data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
  74. data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
  75. data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
  76. data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
  77. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -0
  78. data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
  79. data/lib/dm-core/support/assertions.rb +8 -0
  80. data/lib/dm-core/support/chainable.rb +18 -0
  81. data/lib/dm-core/support/deprecate.rb +12 -0
  82. data/lib/dm-core/support/descendant_set.rb +89 -0
  83. data/lib/dm-core/support/equalizer.rb +48 -0
  84. data/lib/dm-core/support/ext/array.rb +22 -0
  85. data/lib/dm-core/support/ext/blank.rb +25 -0
  86. data/lib/dm-core/support/ext/hash.rb +67 -0
  87. data/lib/dm-core/support/ext/module.rb +47 -0
  88. data/lib/dm-core/support/ext/object.rb +57 -0
  89. data/lib/dm-core/support/ext/string.rb +24 -0
  90. data/lib/dm-core/support/ext/try_dup.rb +12 -0
  91. data/lib/dm-core/support/hook.rb +405 -0
  92. data/lib/dm-core/support/inflections.rb +60 -0
  93. data/lib/dm-core/support/inflector/inflections.rb +211 -0
  94. data/lib/dm-core/support/inflector/methods.rb +151 -0
  95. data/lib/dm-core/support/lazy_array.rb +451 -0
  96. data/lib/dm-core/support/local_object_space.rb +13 -0
  97. data/lib/dm-core/support/logger.rb +201 -0
  98. data/lib/dm-core/support/mash.rb +176 -0
  99. data/lib/dm-core/support/naming_conventions.rb +90 -0
  100. data/lib/dm-core/support/ordered_set.rb +380 -0
  101. data/lib/dm-core/support/subject.rb +33 -0
  102. data/lib/dm-core/support/subject_set.rb +250 -0
  103. data/lib/dm-core/version.rb +3 -0
  104. data/script/performance.rb +275 -0
  105. data/script/profile.rb +218 -0
  106. data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
  107. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +68 -0
  108. data/spec/public/associations/many_to_many_spec.rb +197 -0
  109. data/spec/public/associations/many_to_one_spec.rb +83 -0
  110. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
  111. data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
  112. data/spec/public/associations/one_to_many_spec.rb +81 -0
  113. data/spec/public/associations/one_to_one_spec.rb +176 -0
  114. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
  115. data/spec/public/collection_spec.rb +69 -0
  116. data/spec/public/finalize_spec.rb +76 -0
  117. data/spec/public/model/hook_spec.rb +246 -0
  118. data/spec/public/model/property_spec.rb +88 -0
  119. data/spec/public/model/relationship_spec.rb +1040 -0
  120. data/spec/public/model_spec.rb +462 -0
  121. data/spec/public/property/binary_spec.rb +41 -0
  122. data/spec/public/property/boolean_spec.rb +22 -0
  123. data/spec/public/property/class_spec.rb +28 -0
  124. data/spec/public/property/date_spec.rb +22 -0
  125. data/spec/public/property/date_time_spec.rb +22 -0
  126. data/spec/public/property/decimal_spec.rb +23 -0
  127. data/spec/public/property/discriminator_spec.rb +135 -0
  128. data/spec/public/property/float_spec.rb +22 -0
  129. data/spec/public/property/integer_spec.rb +22 -0
  130. data/spec/public/property/object_spec.rb +107 -0
  131. data/spec/public/property/serial_spec.rb +22 -0
  132. data/spec/public/property/string_spec.rb +22 -0
  133. data/spec/public/property/text_spec.rb +63 -0
  134. data/spec/public/property/time_spec.rb +22 -0
  135. data/spec/public/property_spec.rb +341 -0
  136. data/spec/public/resource_spec.rb +288 -0
  137. data/spec/public/sel_spec.rb +53 -0
  138. data/spec/public/setup_spec.rb +145 -0
  139. data/spec/public/shared/association_collection_shared_spec.rb +309 -0
  140. data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
  141. data/spec/public/shared/collection_shared_spec.rb +1667 -0
  142. data/spec/public/shared/finder_shared_spec.rb +1629 -0
  143. data/spec/rcov.opts +6 -0
  144. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  145. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
  146. data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
  147. data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
  148. data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
  149. data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
  150. data/spec/semipublic/associations/relationship_spec.rb +200 -0
  151. data/spec/semipublic/associations_spec.rb +177 -0
  152. data/spec/semipublic/collection_spec.rb +110 -0
  153. data/spec/semipublic/model_spec.rb +96 -0
  154. data/spec/semipublic/property/binary_spec.rb +13 -0
  155. data/spec/semipublic/property/boolean_spec.rb +47 -0
  156. data/spec/semipublic/property/class_spec.rb +33 -0
  157. data/spec/semipublic/property/date_spec.rb +43 -0
  158. data/spec/semipublic/property/date_time_spec.rb +46 -0
  159. data/spec/semipublic/property/decimal_spec.rb +83 -0
  160. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  161. data/spec/semipublic/property/float_spec.rb +82 -0
  162. data/spec/semipublic/property/integer_spec.rb +82 -0
  163. data/spec/semipublic/property/lookup_spec.rb +29 -0
  164. data/spec/semipublic/property/serial_spec.rb +13 -0
  165. data/spec/semipublic/property/string_spec.rb +13 -0
  166. data/spec/semipublic/property/text_spec.rb +31 -0
  167. data/spec/semipublic/property/time_spec.rb +50 -0
  168. data/spec/semipublic/property_spec.rb +114 -0
  169. data/spec/semipublic/query/conditions/comparison_spec.rb +1501 -0
  170. data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
  171. data/spec/semipublic/query/path_spec.rb +471 -0
  172. data/spec/semipublic/query_spec.rb +3682 -0
  173. data/spec/semipublic/resource/state/clean_spec.rb +88 -0
  174. data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
  175. data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
  176. data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
  177. data/spec/semipublic/resource/state/transient_spec.rb +162 -0
  178. data/spec/semipublic/resource/state_spec.rb +230 -0
  179. data/spec/semipublic/resource_spec.rb +23 -0
  180. data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
  181. data/spec/semipublic/shared/resource_shared_spec.rb +199 -0
  182. data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
  183. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  184. data/spec/spec.opts +5 -0
  185. data/spec/spec_helper.rb +38 -0
  186. data/spec/support/core_ext/hash.rb +10 -0
  187. data/spec/support/core_ext/inheritable_attributes.rb +46 -0
  188. data/spec/support/properties/huge_integer.rb +17 -0
  189. data/spec/unit/array_spec.rb +23 -0
  190. data/spec/unit/blank_spec.rb +73 -0
  191. data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
  192. data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
  193. data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
  194. data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
  195. data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
  196. data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
  197. data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
  198. data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
  199. data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
  200. data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
  201. data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
  202. data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
  203. data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
  204. data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
  205. data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
  206. data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
  207. data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
  208. data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
  209. data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
  210. data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
  211. data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
  212. data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
  213. data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
  214. data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
  215. data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
  216. data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
  217. data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
  218. data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
  219. data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
  220. data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
  221. data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
  222. data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
  223. data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
  224. data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
  225. data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
  226. data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
  227. data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
  228. data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
  229. data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
  230. data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
  231. data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
  232. data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
  233. data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
  234. data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
  235. data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
  236. data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
  237. data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
  238. data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
  239. data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
  240. data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
  241. data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
  242. data/spec/unit/hash_spec.rb +28 -0
  243. data/spec/unit/hook_spec.rb +1235 -0
  244. data/spec/unit/inflections_spec.rb +16 -0
  245. data/spec/unit/lazy_array_spec.rb +1949 -0
  246. data/spec/unit/mash_spec.rb +312 -0
  247. data/spec/unit/module_spec.rb +71 -0
  248. data/spec/unit/object_spec.rb +38 -0
  249. data/spec/unit/try_dup_spec.rb +46 -0
  250. data/tasks/ci.rake +1 -0
  251. data/tasks/spec.rake +38 -0
  252. data/tasks/yard.rake +9 -0
  253. data/tasks/yardstick.rake +19 -0
  254. metadata +365 -0
@@ -0,0 +1,21 @@
1
+ module DataMapper
2
+ class Property
3
+ class Binary < String
4
+
5
+ if RUBY_VERSION >= "1.9"
6
+
7
+ def load(value)
8
+ super.dup.force_encoding("BINARY") unless value.nil?
9
+ end
10
+
11
+ def dump(value)
12
+ value.dup.force_encoding("BINARY") unless value.nil?
13
+ rescue
14
+ value
15
+ end
16
+
17
+ end
18
+
19
+ end # class Binary
20
+ end # class Property
21
+ end # module DataMapper
@@ -0,0 +1,20 @@
1
+ module DataMapper
2
+ class Property
3
+ class Boolean < Object
4
+ load_as ::TrueClass
5
+ dump_as ::TrueClass
6
+ coercion_method :to_boolean
7
+
8
+ # @api semipublic
9
+ def value_dumped?(value)
10
+ value_loaded?(value)
11
+ end
12
+
13
+ # @api semipublic
14
+ def value_loaded?(value)
15
+ value == true || value == false
16
+ end
17
+
18
+ end # class Boolean
19
+ end # class Property
20
+ end # module DataMapper
@@ -0,0 +1,17 @@
1
+ module DataMapper
2
+ class Property
3
+ class Class < Object
4
+ load_as ::Class
5
+ dump_as ::Class
6
+ coercion_method :to_constant
7
+
8
+ # @api semipublic
9
+ def typecast(value)
10
+ DataMapper::Ext::Module.find_const(model, value.to_s) unless value.nil?
11
+ rescue NameError
12
+ value
13
+ end
14
+
15
+ end # class Class
16
+ end # class Property
17
+ end # module DataMapper
@@ -0,0 +1,10 @@
1
+ module DataMapper
2
+ class Property
3
+ class Date < Object
4
+ load_as ::Date
5
+ dump_as ::Date
6
+ coercion_method :to_date
7
+
8
+ end # class Date
9
+ end # class Property
10
+ end # module DataMapper
@@ -0,0 +1,10 @@
1
+ module DataMapper
2
+ class Property
3
+ class DateTime < Object
4
+ load_as ::DateTime
5
+ dump_as ::DateTime
6
+ coercion_method :to_datetime
7
+
8
+ end # class DateTime
9
+ end # class Property
10
+ end # module DataMapper
@@ -0,0 +1,36 @@
1
+ module DataMapper
2
+ class Property
3
+ class Decimal < Numeric
4
+ load_as BigDecimal
5
+ dump_as BigDecimal
6
+ coercion_method :to_decimal
7
+
8
+ DEFAULT_PRECISION = 10
9
+ DEFAULT_SCALE = 0
10
+
11
+ precision(DEFAULT_PRECISION)
12
+ scale(DEFAULT_SCALE)
13
+
14
+ protected
15
+
16
+ def initialize(model, name, options = {})
17
+ super
18
+
19
+ [ :scale, :precision ].each do |key|
20
+ unless @options.key?(key)
21
+ warn "options[#{key.inspect}] should be set for #{self.class}, defaulting to #{send(key).inspect} (#{caller.first})"
22
+ end
23
+ end
24
+
25
+ unless @scale >= 0
26
+ raise ArgumentError, "scale must be equal to or greater than 0, but was #{@scale.inspect}"
27
+ end
28
+
29
+ unless @precision >= @scale
30
+ raise ArgumentError, "precision must be equal to or greater than scale, but was #{@precision.inspect} and scale was #{@scale.inspect}"
31
+ end
32
+ end
33
+
34
+ end # class Decimal
35
+ end # class Property
36
+ end # module DataMapper
@@ -0,0 +1,44 @@
1
+ module DataMapper
2
+ class Property
3
+ class Discriminator < Class
4
+ default lambda { |resource, property| resource.model }
5
+ required true
6
+
7
+ # @api private
8
+ def bind
9
+ model.extend Model unless model < Model
10
+ end
11
+
12
+ module Model
13
+ def inherited(model)
14
+ super # setup self.descendants
15
+ set_discriminator_scope_for(model)
16
+ end
17
+
18
+ def new(*args, &block)
19
+ if args.size == 1 && args.first.kind_of?(Hash)
20
+ discriminator = properties(repository_name).discriminator
21
+
22
+ if discriminator_value = args.first[discriminator.name]
23
+ model = discriminator.typecast(discriminator_value)
24
+
25
+ if model.kind_of?(Model) && !model.equal?(self)
26
+ return model.new(*args, &block)
27
+ end
28
+ end
29
+ end
30
+
31
+ super
32
+ end
33
+
34
+ private
35
+
36
+ def set_discriminator_scope_for(model)
37
+ discriminator = self.properties.discriminator
38
+ default_scope = model.default_scope(discriminator.repository_name)
39
+ default_scope.update(discriminator.name => model.descendants.dup << model)
40
+ end
41
+ end
42
+ end # class Discriminator
43
+ end # module Property
44
+ end # module DataMapper
@@ -0,0 +1,16 @@
1
+ module DataMapper
2
+ class Property
3
+ class Float < Numeric
4
+ load_as ::Float
5
+ dump_as ::Float
6
+ coercion_method :to_float
7
+
8
+ DEFAULT_PRECISION = 10
9
+ DEFAULT_SCALE = nil
10
+
11
+ precision(DEFAULT_PRECISION)
12
+ scale(DEFAULT_SCALE)
13
+
14
+ end # class Float
15
+ end # class Property
16
+ end # module DataMapper
@@ -0,0 +1,22 @@
1
+ module DataMapper
2
+ class Property
3
+ class Integer < Numeric
4
+ load_as ::Integer
5
+ dump_as ::Integer
6
+ coercion_method :to_integer
7
+
8
+ accept_options :serial
9
+
10
+ protected
11
+
12
+ # @api semipublic
13
+ def initialize(model, name, options = {})
14
+ if options.key?(:serial) && !kind_of?(Serial)
15
+ raise "Integer #{name} with explicit :serial option is deprecated, use Serial instead (#{caller[2]})"
16
+ end
17
+ super
18
+ end
19
+
20
+ end # class Integer
21
+ end # class Property
22
+ end # module DataMapper
@@ -0,0 +1,22 @@
1
+ module DataMapper
2
+ class Property
3
+ # Exception raised when DataMapper is about to work with
4
+ # invalid property values.
5
+ class InvalidValueError < StandardError
6
+ attr_reader :property, :value
7
+
8
+ def initialize(property, value)
9
+ msg = "Invalid value %s for property %s (%s) on model %s" %
10
+ [ value.inspect,
11
+ property.name.inspect,
12
+ property.class.name,
13
+ property.model.name
14
+ ]
15
+ super(msg)
16
+ @property = property
17
+ @value = value
18
+ end
19
+
20
+ end # class InvalidValueError
21
+ end # class Property
22
+ end # module DataMapper
@@ -0,0 +1,27 @@
1
+ module DataMapper
2
+ class Property
3
+ module Lookup
4
+
5
+ # Provides transparent access to the Properties defined in
6
+ # {Property}.
7
+ #
8
+ # @param [Symbol] name
9
+ # The name of the property to lookup.
10
+ #
11
+ # @return [Property]
12
+ # The property with the given name.
13
+ #
14
+ # @raise [NameError]
15
+ # The property could not be found.
16
+ #
17
+ # @api private
18
+ #
19
+ # @since 1.0.1
20
+ #
21
+ def const_missing(name)
22
+ Property.find_class(name.to_s) || super
23
+ end
24
+
25
+ end # module Lookup
26
+ end # class Property
27
+ end # module DataMapper
@@ -0,0 +1,38 @@
1
+ module DataMapper
2
+ class Property
3
+ class Numeric < Object
4
+ accept_options :precision, :scale, :min, :max
5
+
6
+ attr_reader :precision, :scale, :min, :max
7
+
8
+ DEFAULT_NUMERIC_MIN = 0
9
+ DEFAULT_NUMERIC_MAX = 2**31-1
10
+
11
+ protected
12
+
13
+ def initialize(model, name, options = {})
14
+ super
15
+
16
+ if kind_of?(Decimal) || kind_of?(Float)
17
+ @precision = @options.fetch(:precision)
18
+ @scale = @options.fetch(:scale)
19
+
20
+ unless @precision > 0
21
+ raise ArgumentError, "precision must be greater than 0, but was #{@precision.inspect}"
22
+ end
23
+ end
24
+
25
+ if @options.key?(:min) || @options.key?(:max)
26
+ @min = @options.fetch(:min, self.class::DEFAULT_NUMERIC_MIN)
27
+ @max = @options.fetch(:max, self.class::DEFAULT_NUMERIC_MAX)
28
+
29
+ if @max < DEFAULT_NUMERIC_MIN && !@options.key?(:min)
30
+ raise ArgumentError, "min should be specified when the max is less than #{DEFAULT_NUMERIC_MIN}"
31
+ elsif @max < @min
32
+ raise ArgumentError, "max must be less than the min, but was #{@max} while the min was #{@min}"
33
+ end
34
+ end
35
+ end
36
+ end # class Numeric
37
+ end # class Property
38
+ end # module DataMapper
@@ -0,0 +1,34 @@
1
+ module DataMapper
2
+ class Property
3
+ class Object < Property
4
+ load_as ::Object
5
+ dump_as ::Object
6
+ coercion_method :to_object
7
+
8
+ # @api semipublic
9
+ def dump(value)
10
+ instance_of?(Object) ? marshal(value) : value
11
+ end
12
+
13
+ # @api semipublic
14
+ def load(value)
15
+ typecast(instance_of?(Object) ? unmarshal(value) : value)
16
+ end
17
+
18
+ # @api semipublic
19
+ def marshal(value)
20
+ [ Marshal.dump(value) ].pack('m') unless value.nil?
21
+ end
22
+
23
+ # @api semipublic
24
+ def unmarshal(value)
25
+ Marshal.load(value.unpack('m').first) unless value.nil?
26
+ end
27
+
28
+ # @api private
29
+ def to_child_key
30
+ self.class
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module DataMapper
2
+ class Property
3
+ class Serial < Integer
4
+ serial true
5
+ min 1
6
+
7
+ # @api private
8
+ def to_child_key
9
+ Property::Integer
10
+ end
11
+
12
+ end # class Text
13
+ end # module Property
14
+ end # module DataMapper
@@ -0,0 +1,38 @@
1
+ module DataMapper
2
+ class Property
3
+ class String < Object
4
+ load_as ::String
5
+ dump_as ::String
6
+ coercion_method :to_string
7
+
8
+ accept_options :length
9
+
10
+ DEFAULT_LENGTH = 50
11
+ length(DEFAULT_LENGTH)
12
+
13
+ # Returns maximum property length (if applicable).
14
+ # This usually only makes sense when property is of
15
+ # type Range or custom
16
+ #
17
+ # @return [Integer, nil]
18
+ # the maximum length of this property
19
+ #
20
+ # @api semipublic
21
+ def length
22
+ if @length.kind_of?(Range)
23
+ @length.max
24
+ else
25
+ @length
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def initialize(model, name, options = {})
32
+ super
33
+ @length = @options.fetch(:length)
34
+ end
35
+
36
+ end # class String
37
+ end # class Property
38
+ end # module DataMapper
@@ -0,0 +1,9 @@
1
+ module DataMapper
2
+ class Property
3
+ class Text < String
4
+ length 65535
5
+ lazy true
6
+
7
+ end # class Text
8
+ end # class Property
9
+ end # module DataMapper
@@ -0,0 +1,10 @@
1
+ module DataMapper
2
+ class Property
3
+ class Time < Object
4
+ load_as ::Time
5
+ dump_as ::Time
6
+ coercion_method :to_time
7
+
8
+ end # class Time
9
+ end # class Property
10
+ end # module DataMapper
@@ -0,0 +1,177 @@
1
+ module DataMapper
2
+ # Set of Property objects, used to associate
3
+ # queries with set of fields it performed over,
4
+ # to represent composite keys (esp. for associations)
5
+ # and so on.
6
+ class PropertySet < SubjectSet
7
+ include Enumerable
8
+
9
+ def <<(property)
10
+ clear_cache
11
+ super
12
+ end
13
+
14
+ # Make sure that entry is part of this PropertySet
15
+ #
16
+ # @param [#to_s] name
17
+ # @param [#name] entry
18
+ #
19
+ # @return [#name]
20
+ # the entry that is now part of this PropertySet
21
+ #
22
+ # @api semipublic
23
+ def []=(name, entry)
24
+ warn "#{self.class}#[]= is deprecated. Use #{self.class}#<< instead: #{caller.first}"
25
+ raise "#{entry.class} is not added with the correct name" unless name && name.to_s == entry.name.to_s
26
+ self << entry
27
+ entry
28
+ end
29
+
30
+ def |(other)
31
+ self.class.new(to_a | other.to_a)
32
+ end
33
+
34
+ def &(other)
35
+ self.class.new(to_a & other.to_a)
36
+ end
37
+
38
+ def -(other)
39
+ self.class.new(to_a - other.to_a)
40
+ end
41
+
42
+ def +(other)
43
+ self.class.new(to_a + other.to_a)
44
+ end
45
+
46
+ def ==(other)
47
+ to_a == other.to_a
48
+ end
49
+
50
+ # TODO: make PropertySet#reject return a PropertySet instance
51
+ # @api semipublic
52
+ def defaults
53
+ @defaults ||= self.class.new(key | [ discriminator ].compact | reject { |property| property.lazy? }).freeze
54
+ end
55
+
56
+ # @api semipublic
57
+ def key
58
+ @key ||= self.class.new(select { |property| property.key? }).freeze
59
+ end
60
+
61
+ # @api semipublic
62
+ def discriminator
63
+ @discriminator ||= detect { |property| property.kind_of?(Property::Discriminator) }
64
+ end
65
+
66
+ # @api semipublic
67
+ def indexes
68
+ index_hash = {}
69
+ each { |property| parse_index(property.index, property.field, index_hash) }
70
+ index_hash
71
+ end
72
+
73
+ # @api semipublic
74
+ def unique_indexes
75
+ index_hash = {}
76
+ each { |property| parse_index(property.unique_index, property.field, index_hash) }
77
+ index_hash
78
+ end
79
+
80
+ # @api semipublic
81
+ def get(resource)
82
+ return [] if resource.nil?
83
+ map { |property| resource.__send__(property.name) }
84
+ end
85
+
86
+ # @api semipublic
87
+ def get!(resource)
88
+ map { |property| property.get!(resource) }
89
+ end
90
+
91
+ # @api semipublic
92
+ def set(resource, values)
93
+ zip(values) { |property, value| resource.__send__("#{property.name}=", value) }
94
+ end
95
+
96
+ # @api semipublic
97
+ def set!(resource, values)
98
+ zip(values) { |property, value| property.set!(resource, value) }
99
+ end
100
+
101
+ # @api semipublic
102
+ def loaded?(resource)
103
+ all? { |property| property.loaded?(resource) }
104
+ end
105
+
106
+ # @api semipublic
107
+ def valid?(values)
108
+ zip(values.nil? ? [] : values).all? { |property, value| property.valid?(value) }
109
+ end
110
+
111
+ # @api semipublic
112
+ def typecast(values)
113
+ zip(values.nil? ? [] : values).map { |property, value| property.typecast(value) }
114
+ end
115
+
116
+ # @api private
117
+ def property_contexts(property)
118
+ contexts = []
119
+ lazy_contexts.each do |context, properties|
120
+ contexts << context if properties.include?(property)
121
+ end
122
+ contexts
123
+ end
124
+
125
+ # @api private
126
+ def lazy_context(context)
127
+ lazy_contexts[context] ||= []
128
+ end
129
+
130
+ # @api private
131
+ def in_context(properties)
132
+ properties_in_context = properties.map do |property|
133
+ if (contexts = property_contexts(property)).any?
134
+ lazy_contexts.values_at(*contexts)
135
+ else
136
+ property
137
+ end
138
+ end
139
+
140
+ properties_in_context.flatten.uniq
141
+ end
142
+
143
+ # @api private
144
+ def field_map
145
+ Hash[ map { |property| [ property.field, property ] } ]
146
+ end
147
+
148
+ def inspect
149
+ to_a.inspect
150
+ end
151
+
152
+ private
153
+
154
+ # @api private
155
+ def clear_cache
156
+ @defaults, @key, @discriminator = nil
157
+ end
158
+
159
+ # @api private
160
+ def lazy_contexts
161
+ @lazy_contexts ||= {}
162
+ end
163
+
164
+ # @api private
165
+ def parse_index(index, property, index_hash)
166
+ case index
167
+ when true
168
+ index_hash[property] = [ property ]
169
+ when Symbol
170
+ index_hash[index] ||= []
171
+ index_hash[index] << property
172
+ when Array
173
+ index.each { |idx| parse_index(idx, property, index_hash) }
174
+ end
175
+ end
176
+ end # class PropertySet
177
+ end # module DataMapper