dm-core 1.1.0 → 1.2.0.rc1

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 (104) hide show
  1. data/Gemfile +13 -11
  2. data/README.rdoc +1 -1
  3. data/Rakefile +1 -2
  4. data/VERSION +1 -1
  5. data/dm-core.gemspec +30 -176
  6. data/lib/dm-core.rb +32 -67
  7. data/lib/dm-core/adapters/abstract_adapter.rb +1 -2
  8. data/lib/dm-core/associations/many_to_many.rb +11 -5
  9. data/lib/dm-core/associations/many_to_one.rb +17 -2
  10. data/lib/dm-core/associations/one_to_many.rb +16 -0
  11. data/lib/dm-core/backwards.rb +13 -0
  12. data/lib/dm-core/collection.rb +1 -1
  13. data/lib/dm-core/model.rb +99 -41
  14. data/lib/dm-core/model/property.rb +24 -27
  15. data/lib/dm-core/model/relationship.rb +22 -28
  16. data/lib/dm-core/property.rb +37 -50
  17. data/lib/dm-core/property/boolean.rb +6 -10
  18. data/lib/dm-core/property/date.rb +0 -2
  19. data/lib/dm-core/property/date_time.rb +0 -2
  20. data/lib/dm-core/property/decimal.rb +5 -1
  21. data/lib/dm-core/property/discriminator.rb +24 -26
  22. data/lib/dm-core/property/float.rb +5 -1
  23. data/lib/dm-core/property/numeric.rb +6 -9
  24. data/lib/dm-core/property/string.rb +2 -1
  25. data/lib/dm-core/property/time.rb +0 -2
  26. data/lib/dm-core/property/typecast/time.rb +7 -2
  27. data/lib/dm-core/property_set.rb +1 -3
  28. data/lib/dm-core/query.rb +3 -10
  29. data/lib/dm-core/query/conditions/comparison.rb +5 -1
  30. data/lib/dm-core/query/conditions/operation.rb +1 -1
  31. data/lib/dm-core/relationship_set.rb +0 -2
  32. data/lib/dm-core/resource.rb +27 -28
  33. data/lib/dm-core/resource/{state.rb → persistence_state.rb} +2 -2
  34. data/lib/dm-core/resource/{state → persistence_state}/clean.rb +4 -4
  35. data/lib/dm-core/resource/{state → persistence_state}/deleted.rb +2 -2
  36. data/lib/dm-core/resource/{state → persistence_state}/dirty.rb +2 -2
  37. data/lib/dm-core/resource/{state → persistence_state}/immutable.rb +3 -3
  38. data/lib/dm-core/resource/{state → persistence_state}/persisted.rb +3 -3
  39. data/lib/dm-core/resource/{state → persistence_state}/transient.rb +3 -3
  40. data/lib/dm-core/spec/lib/adapter_helpers.rb +2 -5
  41. data/lib/dm-core/spec/setup.rb +3 -2
  42. data/lib/dm-core/spec/shared/public/property_spec.rb +8 -0
  43. data/lib/dm-core/spec/shared/resource_spec.rb +14 -0
  44. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +1 -1
  45. data/lib/dm-core/support/descendant_set.rb +0 -2
  46. data/lib/dm-core/support/ext/array.rb +0 -19
  47. data/lib/dm-core/support/ext/blank.rb +1 -0
  48. data/lib/dm-core/support/hook.rb +0 -3
  49. data/lib/dm-core/support/naming_conventions.rb +6 -0
  50. data/lib/dm-core/support/ordered_set.rb +0 -2
  51. data/lib/dm-core/support/subject_set.rb +0 -2
  52. data/lib/dm-core/version.rb +1 -1
  53. data/spec/public/associations/many_to_many_spec.rb +0 -1
  54. data/spec/public/model/property_spec.rb +55 -9
  55. data/spec/public/model/relationship_spec.rb +24 -2
  56. data/spec/public/model_spec.rb +32 -0
  57. data/spec/public/property/binary_spec.rb +14 -6
  58. data/spec/public/property/boolean_spec.rb +14 -6
  59. data/spec/public/property/class_spec.rb +14 -6
  60. data/spec/public/property/date_spec.rb +14 -6
  61. data/spec/public/property/date_time_spec.rb +14 -6
  62. data/spec/public/property/decimal_spec.rb +10 -2
  63. data/spec/public/property/discriminator_spec.rb +15 -1
  64. data/spec/public/property/float_spec.rb +14 -6
  65. data/spec/public/property/integer_spec.rb +14 -6
  66. data/spec/public/property/object_spec.rb +8 -0
  67. data/spec/public/property/serial_spec.rb +14 -6
  68. data/spec/public/property/string_spec.rb +14 -6
  69. data/spec/public/property/text_spec.rb +14 -6
  70. data/spec/public/property/time_spec.rb +14 -6
  71. data/spec/public/resource_spec.rb +58 -0
  72. data/spec/public/shared/finder_shared_spec.rb +8 -4
  73. data/spec/semipublic/associations/many_to_many_spec.rb +2 -0
  74. data/spec/semipublic/associations/many_to_one_spec.rb +2 -0
  75. data/spec/semipublic/associations/one_to_many_spec.rb +2 -0
  76. data/spec/semipublic/associations/one_to_one_spec.rb +2 -0
  77. data/spec/semipublic/property/binary_spec.rb +5 -5
  78. data/spec/semipublic/property/boolean_spec.rb +5 -5
  79. data/spec/semipublic/property/class_spec.rb +5 -5
  80. data/spec/semipublic/property/date_spec.rb +5 -5
  81. data/spec/semipublic/property/date_time_spec.rb +5 -5
  82. data/spec/semipublic/property/decimal_spec.rb +2 -2
  83. data/spec/semipublic/property/discriminator_spec.rb +5 -5
  84. data/spec/semipublic/property/float_spec.rb +5 -5
  85. data/spec/semipublic/property/integer_spec.rb +5 -5
  86. data/spec/semipublic/property/lookup_spec.rb +3 -3
  87. data/spec/semipublic/property/serial_spec.rb +5 -5
  88. data/spec/semipublic/property/string_spec.rb +5 -5
  89. data/spec/semipublic/property/text_spec.rb +5 -5
  90. data/spec/semipublic/property/time_spec.rb +5 -5
  91. data/spec/semipublic/query/conditions/comparison_spec.rb +44 -4
  92. data/spec/semipublic/query_spec.rb +2 -11
  93. data/spec/semipublic/resource/state/clean_spec.rb +6 -6
  94. data/spec/semipublic/resource/state/deleted_spec.rb +4 -4
  95. data/spec/semipublic/resource/state/dirty_spec.rb +8 -8
  96. data/spec/semipublic/resource/state/immutable_spec.rb +6 -6
  97. data/spec/semipublic/resource/state/transient_spec.rb +5 -5
  98. data/spec/semipublic/resource/state_spec.rb +15 -15
  99. data/spec/semipublic/shared/resource_shared_spec.rb +7 -1
  100. data/spec/semipublic/shared/resource_state_shared_spec.rb +8 -8
  101. data/spec/unit/array_spec.rb +0 -14
  102. data/spec/unit/blank_spec.rb +11 -0
  103. metadata +70 -188
  104. data/lib/dm-core/support/inflector.rb +0 -3
@@ -8,6 +8,7 @@ module DataMapper
8
8
  accept_options :length
9
9
 
10
10
  DEFAULT_LENGTH = 50
11
+ length(DEFAULT_LENGTH)
11
12
 
12
13
  # Returns maximum property length (if applicable).
13
14
  # This usually only makes sense when property is of
@@ -29,7 +30,7 @@ module DataMapper
29
30
 
30
31
  def initialize(model, name, options = {})
31
32
  super
32
- @length = @options.fetch(:length, DEFAULT_LENGTH)
33
+ @length = @options.fetch(:length)
33
34
  end
34
35
 
35
36
  # Typecast a value to a String
@@ -1,5 +1,3 @@
1
- require 'dm-core/property/typecast/time'
2
-
3
1
  module DataMapper
4
2
  class Property
5
3
  class Time < Object
@@ -15,14 +15,19 @@ module DataMapper
15
15
  #
16
16
  # @api private
17
17
  def extract_time(value)
18
- mash = value.respond_to?(:to_mash) ? value.to_mash : DataMapper::Ext::Hash.to_mash(value)
18
+ mash = if value.respond_to?(:to_mash)
19
+ value.to_mash
20
+ else
21
+ DataMapper::Ext::Hash.to_mash(value)
22
+ end
23
+
19
24
  now = ::Time.now
20
25
 
21
26
  [ :year, :month, :day, :hour, :min, :sec ].map do |segment|
22
27
  typecast_to_numeric(mash.fetch(segment, now.send(segment)), :to_i)
23
28
  end
24
29
  end
25
- end # Numeric
30
+ end # Time
26
31
  end # Typecast
27
32
  end # Property
28
33
  end # DataMapper
@@ -1,5 +1,3 @@
1
- require 'dm-core/support/subject_set'
2
-
3
1
  module DataMapper
4
2
  # Set of Property objects, used to associate
5
3
  # queries with set of fields it performed over,
@@ -144,7 +142,7 @@ module DataMapper
144
142
 
145
143
  # @api private
146
144
  def field_map
147
- DataMapper::Ext::Array.to_hash(map { |property| [ property.field, property ] })
145
+ Hash[ map { |property| [ property.field, property ] } ]
148
146
  end
149
147
 
150
148
  def inspect
@@ -1120,19 +1120,12 @@ module DataMapper
1120
1120
 
1121
1121
  # Normalize the unique attribute
1122
1122
  #
1123
- # If any links are present, and the unique attribute was not explicitly
1124
- # specified, then make sure the query is marked as unique. The exception
1125
- # to this rule is links where there is known to be 0..1 records on the
1126
- # the other side, such as belongs_to or a has 1. In this case, there
1127
- # is no need to explicitly mark the query unique. This in turn allows
1128
- # sane ordering on fields of the links, since no redundant GROUP BY
1129
- # clause will be generated.
1123
+ # If any links are present, and the unique attribute was not
1124
+ # explicitly specified, then make sure the query is marked as unique
1130
1125
  #
1131
1126
  # @api private
1132
1127
  def normalize_unique
1133
- unless @options.key?(:unique)
1134
- @unique = @links.reject {|x| x.min.between?(0, 1) && x.max == 1 }.any?
1135
- end
1128
+ @unique = links.any? unless @options.key?(:unique)
1136
1129
  end
1137
1130
 
1138
1131
  # Append conditions to this Query
@@ -102,7 +102,7 @@ module DataMapper
102
102
  class AbstractComparison
103
103
  extend Equalizer
104
104
 
105
- equalize :slug, :subject, :value
105
+ equalize :subject, :value
106
106
 
107
107
  # @api semipublic
108
108
  attr_accessor :parent
@@ -797,6 +797,7 @@ module DataMapper
797
797
  #
798
798
  # @api semipublic
799
799
  def matches?(record)
800
+ return false if expected.nil?
800
801
  record_value = record_value(record)
801
802
  !record_value.nil? && record_value > expected
802
803
  end
@@ -827,6 +828,7 @@ module DataMapper
827
828
  #
828
829
  # @api semipublic
829
830
  def matches?(record)
831
+ return false if expected.nil?
830
832
  record_value = record_value(record)
831
833
  !record_value.nil? && record_value < expected
832
834
  end
@@ -857,6 +859,7 @@ module DataMapper
857
859
  #
858
860
  # @api semipublic
859
861
  def matches?(record)
862
+ return false if expected.nil?
860
863
  record_value = record_value(record)
861
864
  !record_value.nil? && record_value >= expected
862
865
  end
@@ -885,6 +888,7 @@ module DataMapper
885
888
  #
886
889
  # @api semipublic
887
890
  def matches?(record)
891
+ return false if expected.nil?
888
892
  record_value = record_value(record)
889
893
  !record_value.nil? && record_value <= expected
890
894
  end
@@ -70,7 +70,7 @@ module DataMapper
70
70
  include Enumerable
71
71
  extend Equalizer
72
72
 
73
- equalize :slug, :sorted_operands
73
+ equalize :sorted_operands
74
74
 
75
75
  # Returns the parent operation
76
76
  #
@@ -1,5 +1,3 @@
1
- require 'dm-core/support/subject_set'
2
-
3
1
  module DataMapper
4
2
 
5
3
  # A {SubjectSet} that keeps track of relationships defined in a {Model}
@@ -1,10 +1,6 @@
1
- # TODO: DRY up raise_on_save_failure with attr_accessor_with_default
2
- # once AS branch is merged in
3
-
4
1
  module DataMapper
5
2
  module Resource
6
3
  include DataMapper::Assertions
7
- extend Chainable
8
4
 
9
5
  # @deprecated
10
6
  def self.append_inclusions(*inclusions)
@@ -80,24 +76,24 @@ module DataMapper
80
76
 
81
77
  # Get the persisted state for the resource
82
78
  #
83
- # @return [Resource::State]
79
+ # @return [Resource::PersistenceState]
84
80
  # the current persisted state for the resource
85
81
  #
86
82
  # @api private
87
- def persisted_state
88
- @_state ||= Resource::State::Transient.new(self)
83
+ def persistence_state
84
+ @_persistence_state ||= Resource::PersistenceState::Transient.new(self)
89
85
  end
90
86
 
91
87
  # Set the persisted state for the resource
92
88
  #
93
- # @param [Resource::State]
89
+ # @param [Resource::PersistenceState]
94
90
  # the new persisted state for the resource
95
91
  #
96
92
  # @return [undefined]
97
93
  #
98
94
  # @api private
99
- def persisted_state=(state)
100
- @_state = state
95
+ def persistence_state=(state)
96
+ @_persistence_state = state
101
97
  end
102
98
 
103
99
  # Test if the persisted state is set
@@ -106,8 +102,8 @@ module DataMapper
106
102
  # true if the persisted state is set
107
103
  #
108
104
  # @api private
109
- def persisted_state?
110
- defined?(@_state) ? true : false
105
+ def persistence_state?
106
+ defined?(@_persistence_state) ? true : false
111
107
  end
112
108
 
113
109
  # Repository this resource belongs to in the context of this collection
@@ -153,7 +149,7 @@ module DataMapper
153
149
  #
154
150
  # @api public
155
151
  def new?
156
- persisted_state.kind_of?(State::Transient)
152
+ persistence_state.kind_of?(PersistenceState::Transient)
157
153
  end
158
154
 
159
155
  # Checks if this Resource instance is saved
@@ -163,7 +159,7 @@ module DataMapper
163
159
  #
164
160
  # @api public
165
161
  def saved?
166
- persisted_state.kind_of?(State::Persisted)
162
+ persistence_state.kind_of?(PersistenceState::Persisted)
167
163
  end
168
164
 
169
165
  # Checks if this Resource instance is destroyed
@@ -183,7 +179,8 @@ module DataMapper
183
179
  #
184
180
  # @api public
185
181
  def clean?
186
- persisted_state.kind_of?(State::Clean) || persisted_state.kind_of?(State::Immutable)
182
+ persistence_state.kind_of?(PersistenceState::Clean) ||
183
+ persistence_state.kind_of?(PersistenceState::Immutable)
187
184
  end
188
185
 
189
186
  # Checks if the resource has unsaved changes
@@ -205,7 +202,7 @@ module DataMapper
205
202
  #
206
203
  # @api public
207
204
  def readonly?
208
- persisted_state.kind_of?(State::Immutable)
205
+ persistence_state.kind_of?(PersistenceState::Immutable)
209
206
  end
210
207
 
211
208
  # Returns the value of the attribute.
@@ -240,7 +237,8 @@ module DataMapper
240
237
  #
241
238
  # @api public
242
239
  def attribute_get(name)
243
- persisted_state.get(properties[name])
240
+ property = properties[name]
241
+ persistence_state.get(property) if property
244
242
  end
245
243
 
246
244
  alias_method :[], :attribute_get
@@ -281,7 +279,8 @@ module DataMapper
281
279
  #
282
280
  # @api public
283
281
  def attribute_set(name, value)
284
- self.persisted_state = persisted_state.set(properties[name], value)
282
+ property = properties[name]
283
+ self.persistence_state = persistence_state.set(property, value) if property
285
284
  end
286
285
 
287
286
  alias_method :[]=, :attribute_set
@@ -330,13 +329,13 @@ module DataMapper
330
329
  attributes.each do |name, value|
331
330
  case name
332
331
  when String, Symbol
333
- if model.public_method_defined?(setter = "#{name}=")
332
+ if model.allowed_writer_methods.include?(setter = "#{name}=")
334
333
  __send__(setter, value)
335
334
  else
336
335
  raise ArgumentError, "The attribute '#{name}' is not accessible in #{model}"
337
336
  end
338
337
  when Associations::Relationship, Property
339
- self.persisted_state = persisted_state.set(name, value)
338
+ self.persistence_state = persistence_state.set(name, value)
340
339
  end
341
340
  end
342
341
  end
@@ -360,7 +359,7 @@ module DataMapper
360
359
  clear_subjects
361
360
  end
362
361
 
363
- self.persisted_state = persisted_state.rollback
362
+ self.persistence_state = persistence_state.rollback
364
363
 
365
364
  self
366
365
  end
@@ -552,8 +551,8 @@ module DataMapper
552
551
  #
553
552
  # @api semipublic
554
553
  def original_attributes
555
- if persisted_state.respond_to?(:original_attributes)
556
- persisted_state.original_attributes.dup.freeze
554
+ if persistence_state.respond_to?(:original_attributes)
555
+ persistence_state.original_attributes.dup.freeze
557
556
  else
558
557
  {}.freeze
559
558
  end
@@ -755,7 +754,7 @@ module DataMapper
755
754
  instance_variable_set(ivar, DataMapper::Ext.try_dup(instance_variable_get(ivar)))
756
755
  end
757
756
 
758
- self.persisted_state = persisted_state.class.new(self)
757
+ self.persistence_state = persistence_state.class.new(self)
759
758
  end
760
759
 
761
760
  # Returns name of the repository this object
@@ -954,7 +953,7 @@ module DataMapper
954
953
  #
955
954
  # @api private
956
955
  def _persist
957
- self.persisted_state = persisted_state.commit
956
+ self.persistence_state = persistence_state.commit
958
957
  end
959
958
 
960
959
  # This method executes the hooks before and after resource creation
@@ -997,7 +996,7 @@ module DataMapper
997
996
  #
998
997
  # @api private
999
998
  def _destroy(execute_hooks = true)
1000
- self.persisted_state = persisted_state.delete
999
+ self.persistence_state = persistence_state.delete
1001
1000
  _persist
1002
1001
  end
1003
1002
 
@@ -1127,8 +1126,8 @@ module DataMapper
1127
1126
 
1128
1127
  # @api private
1129
1128
  def set_default_value(subject)
1130
- return unless persisted_state.respond_to?(:set_default_value, true)
1131
- persisted_state.__send__(:set_default_value, subject)
1129
+ return unless persistence_state.respond_to?(:set_default_value, true)
1130
+ persistence_state.__send__(:set_default_value, subject)
1132
1131
  end
1133
1132
 
1134
1133
  # Execute all the queued up hooks for a given type and name
@@ -2,7 +2,7 @@ module DataMapper
2
2
  module Resource
3
3
 
4
4
  # the state of the resource (abstract)
5
- class State
5
+ class PersistenceState
6
6
  extend Equalizer
7
7
 
8
8
  equalize :resource
@@ -70,6 +70,6 @@ module DataMapper
70
70
  set(relationship, get(relationship))
71
71
  end
72
72
 
73
- end # class State
73
+ end # class PersistenceState
74
74
  end # module Resource
75
75
  end # module DataMapper
@@ -1,6 +1,6 @@
1
1
  module DataMapper
2
2
  module Resource
3
- class State
3
+ class PersistenceState
4
4
 
5
5
  # a persisted/unmodified resource
6
6
  class Clean < Persisted
@@ -8,10 +8,10 @@ module DataMapper
8
8
  if not_modified?(subject, value)
9
9
  self
10
10
  else
11
- # assign to persisted_state so that if Dirty#set calls
11
+ # assign to persistence_state so that if Dirty#set calls
12
12
  # a Relationship#set, which modifies a Property, the same
13
13
  # Dirty state instance will be reused.
14
- state = resource.persisted_state = Dirty.new(resource)
14
+ state = resource.persistence_state = Dirty.new(resource)
15
15
  state.set(subject, value)
16
16
  end
17
17
  end
@@ -35,6 +35,6 @@ module DataMapper
35
35
  end
36
36
 
37
37
  end # class Clean
38
- end # class State
38
+ end # class PersistenceState
39
39
  end # module Resource
40
40
  end # module DataMapper
@@ -1,6 +1,6 @@
1
1
  module DataMapper
2
2
  module Resource
3
- class State
3
+ class PersistenceState
4
4
 
5
5
  # a persisted/deleted resource
6
6
  class Deleted < Persisted
@@ -25,6 +25,6 @@ module DataMapper
25
25
  end
26
26
 
27
27
  end # class Deleted
28
- end # class State
28
+ end # class PersistenceState
29
29
  end # module Resource
30
30
  end # module DataMapper
@@ -1,6 +1,6 @@
1
1
  module DataMapper
2
2
  module Resource
3
- class State
3
+ class PersistenceState
4
4
 
5
5
  # a persisted/dirty resource
6
6
  class Dirty < Persisted
@@ -91,6 +91,6 @@ module DataMapper
91
91
  end
92
92
 
93
93
  end # class Dirty
94
- end # class State
94
+ end # class PersistenceState
95
95
  end # module Resource
96
96
  end # module DataMapper
@@ -1,9 +1,9 @@
1
1
  module DataMapper
2
2
  module Resource
3
- class State
3
+ class PersistenceState
4
4
 
5
5
  # a not-persisted/unmodifiable resource
6
- class Immutable < State
6
+ class Immutable < PersistenceState
7
7
  def get(subject, *args)
8
8
  unless subject.loaded?(resource) || subject.kind_of?(Associations::Relationship)
9
9
  raise ImmutableError, 'Immutable resource cannot be lazy loaded'
@@ -29,6 +29,6 @@ module DataMapper
29
29
  end
30
30
 
31
31
  end # class Immutable
32
- end # class State
32
+ end # class PersistenceState
33
33
  end # module Resource
34
34
  end # module DataMapper
@@ -1,9 +1,9 @@
1
1
  module DataMapper
2
2
  module Resource
3
- class State
3
+ class PersistenceState
4
4
 
5
5
  # a persisted resource (abstract)
6
- class Persisted < State
6
+ class Persisted < PersistenceState
7
7
  def get(subject, *args)
8
8
  lazy_load(subject)
9
9
  super
@@ -24,6 +24,6 @@ module DataMapper
24
24
  end
25
25
 
26
26
  end # class Persisted
27
- end # class State
27
+ end # class PersistenceState
28
28
  end # module Resource
29
29
  end # module DataMapper
@@ -1,9 +1,9 @@
1
1
  module DataMapper
2
2
  module Resource
3
- class State
3
+ class PersistenceState
4
4
 
5
5
  # a not-persisted/modifiable resource
6
- class Transient < State
6
+ class Transient < PersistenceState
7
7
  def get(subject, *args)
8
8
  set_default_value(subject)
9
9
  super
@@ -73,6 +73,6 @@ module DataMapper
73
73
  end
74
74
 
75
75
  end # class Transient
76
- end # class State
76
+ end # class PersistenceState
77
77
  end # module Resource
78
78
  end # module DataMapper