dm-core 1.0.0.rc2 → 1.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +3 -4
- data/VERSION +1 -1
- data/dm-core.gemspec +7 -5
- data/lib/dm-core.rb +44 -0
- data/lib/dm-core/adapters.rb +1 -1
- data/lib/dm-core/adapters/abstract_adapter.rb +16 -0
- data/lib/dm-core/collection.rb +2 -2
- data/lib/dm-core/model.rb +64 -53
- data/lib/dm-core/model/property.rb +14 -6
- data/lib/dm-core/model/relationship.rb +10 -18
- data/lib/dm-core/property.rb +10 -10
- data/lib/dm-core/query.rb +8 -18
- data/lib/dm-core/resource.rb +3 -11
- data/lib/dm-core/resource/state.rb +13 -16
- data/lib/dm-core/resource/state/dirty.rb +11 -1
- data/lib/dm-core/resource/state/transient.rb +9 -1
- data/lib/dm-core/spec/lib/adapter_helpers.rb +5 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +2 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +0 -31
- data/lib/dm-core/version.rb +1 -1
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +2 -0
- data/spec/public/associations/many_to_many_spec.rb +2 -1
- data/spec/public/associations/many_to_one_spec.rb +1 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +1 -0
- data/spec/public/associations/one_to_many_spec.rb +2 -0
- data/spec/public/associations/one_to_one_spec.rb +2 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +1 -0
- data/spec/public/collection_spec.rb +2 -0
- data/spec/public/finalize_spec.rb +34 -0
- data/spec/public/model/hook_spec.rb +1 -0
- data/spec/public/model/property_spec.rb +1 -0
- data/spec/public/model/relationship_spec.rb +22 -0
- data/spec/public/model_spec.rb +138 -3
- data/spec/public/property/discriminator_spec.rb +1 -0
- data/spec/public/property/object_spec.rb +1 -0
- data/spec/public/property_spec.rb +13 -4
- data/spec/public/resource_spec.rb +1 -0
- data/spec/public/sel_spec.rb +2 -0
- data/spec/public/shared/collection_shared_spec.rb +0 -45
- data/spec/public/shared/finder_shared_spec.rb +110 -0
- data/spec/public/shared/property_shared_spec.rb +1 -1
- data/spec/rcov.opts +1 -1
- data/spec/semipublic/associations/many_to_many_spec.rb +3 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +2 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +2 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +2 -0
- data/spec/semipublic/associations/relationship_spec.rb +6 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +3 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1 -0
- data/spec/semipublic/query/path_spec.rb +2 -0
- data/spec/semipublic/query_spec.rb +2 -3
- data/spec/semipublic/resource/state/clean_spec.rb +2 -1
- data/spec/semipublic/resource/state/deleted_spec.rb +2 -1
- data/spec/semipublic/resource/state/dirty_spec.rb +42 -20
- data/spec/semipublic/resource/state/immutable_spec.rb +7 -1
- data/spec/semipublic/resource/state/transient_spec.rb +69 -40
- data/spec/semipublic/resource/state_spec.rb +72 -66
- data/spec/semipublic/shared/property_shared_spec.rb +1 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +1 -0
- data/spec/spec_helper.rb +0 -10
- data/tasks/spec.rake +3 -0
- metadata +9 -7
data/lib/dm-core/property.rb
CHANGED
@@ -473,7 +473,7 @@ module DataMapper
|
|
473
473
|
#
|
474
474
|
# @api public
|
475
475
|
def unique?
|
476
|
-
|
476
|
+
!!@unique
|
477
477
|
end
|
478
478
|
|
479
479
|
# Returns the hash of the property name
|
@@ -491,11 +491,11 @@ module DataMapper
|
|
491
491
|
|
492
492
|
# Returns index name if property has index.
|
493
493
|
#
|
494
|
-
# @return [
|
494
|
+
# @return [Boolean, Symbol, Array]
|
495
495
|
# returns true if property is indexed by itself
|
496
496
|
# returns a Symbol if the property is indexed with other properties
|
497
497
|
# returns an Array if the property belongs to multiple indexes
|
498
|
-
# returns
|
498
|
+
# returns false if the property does not belong to any indexes
|
499
499
|
#
|
500
500
|
# @api public
|
501
501
|
def index
|
@@ -505,11 +505,11 @@ module DataMapper
|
|
505
505
|
# Returns true if property has unique index. Serial properties and
|
506
506
|
# keys are unique by default.
|
507
507
|
#
|
508
|
-
# @return [
|
508
|
+
# @return [Boolean, Symbol, Array]
|
509
509
|
# returns true if property is indexed by itself
|
510
510
|
# returns a Symbol if the property is indexed with other properties
|
511
511
|
# returns an Array if the property belongs to multiple indexes
|
512
|
-
# returns
|
512
|
+
# returns false if the property does not belong to any indexes
|
513
513
|
#
|
514
514
|
# @api public
|
515
515
|
def unique_index
|
@@ -794,7 +794,7 @@ module DataMapper
|
|
794
794
|
|
795
795
|
@repository_name = model.repository_name
|
796
796
|
@model = model
|
797
|
-
@name = name.to_s.
|
797
|
+
@name = name.to_s.chomp('?').to_sym
|
798
798
|
@options = predefined_options.merge(options).freeze
|
799
799
|
@instance_variable_name = "@#{@name}".freeze
|
800
800
|
|
@@ -804,13 +804,13 @@ module DataMapper
|
|
804
804
|
@default = @options[:default]
|
805
805
|
|
806
806
|
@serial = @options.fetch(:serial, false)
|
807
|
-
@key = @options.fetch(:key, @serial
|
807
|
+
@key = @options.fetch(:key, @serial)
|
808
|
+
@unique = @options.fetch(:unique, @key ? :key : false)
|
808
809
|
@required = @options.fetch(:required, @key)
|
809
810
|
@allow_nil = @options.fetch(:allow_nil, !@required)
|
810
811
|
@allow_blank = @options.fetch(:allow_blank, !@required)
|
811
|
-
@index = @options.fetch(:index,
|
812
|
-
@unique_index = @options.fetch(:unique_index,
|
813
|
-
@unique = @options.fetch(:unique, @serial || @key || false)
|
812
|
+
@index = @options.fetch(:index, false)
|
813
|
+
@unique_index = @options.fetch(:unique_index, @unique)
|
814
814
|
@lazy = @options.fetch(:lazy, false) && !@key
|
815
815
|
|
816
816
|
determine_visibility
|
data/lib/dm-core/query.rb
CHANGED
@@ -324,10 +324,10 @@ module DataMapper
|
|
324
324
|
# @api semipublic
|
325
325
|
def reverse!
|
326
326
|
# reverse the sort order
|
327
|
-
@order.map! { |direction| direction.reverse! }
|
327
|
+
@order.map! { |direction| direction.dup.reverse! }
|
328
328
|
|
329
329
|
# copy the order to the options
|
330
|
-
@options = @options.merge(:order => @order
|
330
|
+
@options = @options.merge(:order => @order).freeze
|
331
331
|
|
332
332
|
self
|
333
333
|
end
|
@@ -1171,22 +1171,12 @@ module DataMapper
|
|
1171
1171
|
add_condition(condition)
|
1172
1172
|
end
|
1173
1173
|
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
end
|
1181
|
-
end
|
1182
|
-
else
|
1183
|
-
def equality_operator_for_type(bind_value)
|
1184
|
-
case bind_value
|
1185
|
-
when String then :eql
|
1186
|
-
when Enumerable then :in
|
1187
|
-
when Regexp then :regexp
|
1188
|
-
else :eql
|
1189
|
-
end
|
1174
|
+
def equality_operator_for_type(bind_value)
|
1175
|
+
case bind_value
|
1176
|
+
when Model, String then :eql
|
1177
|
+
when Enumerable then :in
|
1178
|
+
when Regexp then :regexp
|
1179
|
+
else :eql
|
1190
1180
|
end
|
1191
1181
|
end
|
1192
1182
|
|
data/lib/dm-core/resource.rb
CHANGED
@@ -755,8 +755,8 @@ module DataMapper
|
|
755
755
|
# attribute values used in the new instance
|
756
756
|
#
|
757
757
|
# @api public
|
758
|
-
def initialize(attributes = {}
|
759
|
-
self.attributes = attributes
|
758
|
+
def initialize(attributes = {}) # :nodoc:
|
759
|
+
self.attributes = attributes || {}
|
760
760
|
end
|
761
761
|
|
762
762
|
# @api private
|
@@ -1009,7 +1009,7 @@ module DataMapper
|
|
1009
1009
|
#
|
1010
1010
|
# @api private
|
1011
1011
|
def _update
|
1012
|
-
self.persisted_state = persisted_state.commit
|
1012
|
+
self.persisted_state = persisted_state.commit
|
1013
1013
|
clean?
|
1014
1014
|
end
|
1015
1015
|
|
@@ -1168,14 +1168,6 @@ module DataMapper
|
|
1168
1168
|
persisted_state.__send__(:set_default_value, subject)
|
1169
1169
|
end
|
1170
1170
|
|
1171
|
-
# @api private
|
1172
|
-
def valid_attributes?
|
1173
|
-
original_attributes.each_key do |property|
|
1174
|
-
return false if property.kind_of?(Property) && !property.valid?(property.get!(self))
|
1175
|
-
end
|
1176
|
-
true
|
1177
|
-
end
|
1178
|
-
|
1179
1171
|
# Execute all the queued up hooks for a given type and name
|
1180
1172
|
#
|
1181
1173
|
# @param [Symbol] type
|
@@ -3,6 +3,10 @@ module DataMapper
|
|
3
3
|
|
4
4
|
# the state of the resource (abstract)
|
5
5
|
class State
|
6
|
+
extend Equalizer
|
7
|
+
|
8
|
+
equalize :resource
|
9
|
+
|
6
10
|
attr_reader :resource
|
7
11
|
|
8
12
|
def initialize(resource)
|
@@ -30,20 +34,6 @@ module DataMapper
|
|
30
34
|
raise NotImplementedError, "#{self.class}#rollback should be implemented"
|
31
35
|
end
|
32
36
|
|
33
|
-
def eql?(other)
|
34
|
-
instance_of?(other.class) &&
|
35
|
-
hash == other.hash
|
36
|
-
end
|
37
|
-
|
38
|
-
def ==(other)
|
39
|
-
self.class <=> other.class &&
|
40
|
-
hash == other.hash
|
41
|
-
end
|
42
|
-
|
43
|
-
def hash
|
44
|
-
resource.object_id.hash
|
45
|
-
end
|
46
|
-
|
47
37
|
private
|
48
38
|
|
49
39
|
def model
|
@@ -70,8 +60,15 @@ module DataMapper
|
|
70
60
|
identity_map[resource.key] = resource
|
71
61
|
end
|
72
62
|
|
73
|
-
def
|
74
|
-
|
63
|
+
def set_child_keys
|
64
|
+
relationships.each do |relationship|
|
65
|
+
set_child_key(relationship)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_child_key(relationship)
|
70
|
+
return unless relationship.loaded?(resource) && relationship.respond_to?(:resource_for)
|
71
|
+
set(relationship, get(relationship))
|
75
72
|
end
|
76
73
|
|
77
74
|
end # class State
|
@@ -17,11 +17,14 @@ module DataMapper
|
|
17
17
|
|
18
18
|
def commit
|
19
19
|
remove_from_identity_map
|
20
|
+
set_child_keys
|
21
|
+
return self unless valid_attributes?
|
20
22
|
update_resource
|
21
23
|
reset_original_attributes
|
22
24
|
reset_resource_key
|
23
|
-
add_to_identity_map
|
24
25
|
Clean.new(resource)
|
26
|
+
ensure
|
27
|
+
add_to_identity_map
|
25
28
|
end
|
26
29
|
|
27
30
|
def rollback
|
@@ -80,6 +83,13 @@ module DataMapper
|
|
80
83
|
original_attributes.clear
|
81
84
|
end
|
82
85
|
|
86
|
+
def valid_attributes?
|
87
|
+
original_attributes.each_key do |property|
|
88
|
+
return false if property.kind_of?(Property) && !property.valid?(property.get!(resource))
|
89
|
+
end
|
90
|
+
true
|
91
|
+
end
|
92
|
+
|
83
93
|
end # class Dirty
|
84
94
|
end # class State
|
85
95
|
end # module Resource
|
@@ -19,10 +19,11 @@ module DataMapper
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def commit
|
22
|
+
set_child_keys
|
22
23
|
set_default_values
|
24
|
+
return self unless valid_attributes?
|
23
25
|
create_resource
|
24
26
|
set_repository
|
25
|
-
reset_original_attributes
|
26
27
|
add_to_identity_map
|
27
28
|
Clean.new(resource)
|
28
29
|
end
|
@@ -64,6 +65,13 @@ module DataMapper
|
|
64
65
|
resource.instance_variable_set(:@_repository, repository)
|
65
66
|
end
|
66
67
|
|
68
|
+
def valid_attributes?
|
69
|
+
properties.all? do |property|
|
70
|
+
value = get(property)
|
71
|
+
property.serial? && value.nil? || property.valid?(value)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
67
75
|
end # class Transient
|
68
76
|
end # class State
|
69
77
|
end # module Resource
|
@@ -26,6 +26,11 @@ module DataMapper
|
|
26
26
|
|
27
27
|
# create all tables and constraints before each spec
|
28
28
|
if @repository.respond_to?(:auto_migrate!)
|
29
|
+
# If we are going to auto-migrate, we must also finalize
|
30
|
+
@repository.scope do
|
31
|
+
DataMapper.finalize
|
32
|
+
end
|
33
|
+
|
29
34
|
@repository.auto_migrate!
|
30
35
|
end
|
31
36
|
end
|
@@ -1177,37 +1177,6 @@ share_examples_for 'A public Resource' do
|
|
1177
1177
|
end
|
1178
1178
|
end
|
1179
1179
|
|
1180
|
-
describe 'invalid resources' do
|
1181
|
-
before do
|
1182
|
-
class ::EmptyObject
|
1183
|
-
include DataMapper::Resource
|
1184
|
-
end
|
1185
|
-
|
1186
|
-
class ::KeylessObject
|
1187
|
-
include DataMapper::Resource
|
1188
|
-
property :name, String
|
1189
|
-
end
|
1190
|
-
end
|
1191
|
-
|
1192
|
-
it 'should raise an error for a resource without attributes' do
|
1193
|
-
lambda { EmptyObject.new }.should raise_error
|
1194
|
-
end
|
1195
|
-
|
1196
|
-
it 'should raise an error for a resource without a key' do
|
1197
|
-
lambda { KeylessObject.new }.should raise_error
|
1198
|
-
end
|
1199
|
-
|
1200
|
-
after do
|
1201
|
-
# clean out invalid models so that global model cleanup
|
1202
|
-
# does not throw an exception when working with models
|
1203
|
-
# in an invalid state
|
1204
|
-
[ EmptyObject, KeylessObject ].each do |model|
|
1205
|
-
Object.send(:remove_const, model.name.to_sym)
|
1206
|
-
DataMapper::Model.descendants.delete(model)
|
1207
|
-
end
|
1208
|
-
end
|
1209
|
-
end
|
1210
|
-
|
1211
1180
|
describe 'lazy loading' do
|
1212
1181
|
before :all do
|
1213
1182
|
rescue_if @skip do
|
data/lib/dm-core/version.rb
CHANGED
@@ -66,7 +66,7 @@ end
|
|
66
66
|
@publication_model = Blog::Publication
|
67
67
|
|
68
68
|
# initialize the join model
|
69
|
-
|
69
|
+
DataMapper.finalize
|
70
70
|
|
71
71
|
@join_model = Blog::ArticleAuthor
|
72
72
|
end
|
@@ -157,6 +157,7 @@ end
|
|
157
157
|
@author_model = Blog::Author
|
158
158
|
@article_model = Blog::Article
|
159
159
|
@publication_model = Blog::Publication
|
160
|
+
DataMapper.finalize
|
160
161
|
|
161
162
|
@join_model = Blog::Site
|
162
163
|
end
|
@@ -58,6 +58,7 @@ describe 'One to One Associations' do
|
|
58
58
|
|
59
59
|
property :name, String, :key => true, :default => 'a default value'
|
60
60
|
end
|
61
|
+
DataMapper.finalize
|
61
62
|
|
62
63
|
@user_model = Blog::User
|
63
64
|
@author_model = Blog::Author
|
@@ -148,6 +149,7 @@ describe 'One to One Through Associations' do
|
|
148
149
|
|
149
150
|
property :name, String, :key => true, :default => 'a default value'
|
150
151
|
end
|
152
|
+
DataMapper.finalize
|
151
153
|
|
152
154
|
@referral_model = Blog::Referral
|
153
155
|
@user_model = Blog::User
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe DataMapper do
|
4
|
+
describe '.setup' do
|
5
|
+
it "should not raise with valid models" do
|
6
|
+
class ::ValidObject
|
7
|
+
include DataMapper::Resource
|
8
|
+
property :id, Integer, :key => true
|
9
|
+
end
|
10
|
+
lambda { DataMapper.finalize }.should_not raise_error
|
11
|
+
DataMapper::Model.descendants.delete(ValidObject)
|
12
|
+
Object.send(:remove_const, :ValidObject)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should raise on an empty model" do
|
16
|
+
class ::EmptyObject
|
17
|
+
include DataMapper::Resource
|
18
|
+
end
|
19
|
+
lambda { DataMapper.finalize }.should raise_error
|
20
|
+
DataMapper::Model.descendants.delete(EmptyObject)
|
21
|
+
Object.send(:remove_const, :EmptyObject)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should raise on a keyless model" do
|
25
|
+
class ::KeylessObject
|
26
|
+
include DataMapper::Resource
|
27
|
+
property :name, String
|
28
|
+
end
|
29
|
+
lambda { DataMapper.finalize }.should raise_error
|
30
|
+
DataMapper::Model.descendants.delete(KeylessObject)
|
31
|
+
Object.send(:remove_const, :KeylessObject)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|