dm-core 1.1.0 → 1.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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