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.
- data/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +35 -0
- data/.yardopts +1 -0
- data/Gemfile +65 -0
- data/LICENSE +20 -0
- data/README.md +269 -0
- data/Rakefile +4 -0
- data/dm-core.gemspec +24 -0
- data/lib/dm-core.rb +292 -0
- data/lib/dm-core/adapters.rb +222 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
- data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
- data/lib/dm-core/associations/many_to_many.rb +499 -0
- data/lib/dm-core/associations/many_to_one.rb +290 -0
- data/lib/dm-core/associations/one_to_many.rb +348 -0
- data/lib/dm-core/associations/one_to_one.rb +86 -0
- data/lib/dm-core/associations/relationship.rb +663 -0
- data/lib/dm-core/backwards.rb +13 -0
- data/lib/dm-core/collection.rb +1515 -0
- data/lib/dm-core/core_ext/kernel.rb +23 -0
- data/lib/dm-core/core_ext/pathname.rb +6 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +7 -0
- data/lib/dm-core/model.rb +874 -0
- data/lib/dm-core/model/hook.rb +103 -0
- data/lib/dm-core/model/is.rb +32 -0
- data/lib/dm-core/model/property.rb +249 -0
- data/lib/dm-core/model/relationship.rb +378 -0
- data/lib/dm-core/model/scope.rb +89 -0
- data/lib/dm-core/property.rb +866 -0
- data/lib/dm-core/property/binary.rb +21 -0
- data/lib/dm-core/property/boolean.rb +20 -0
- data/lib/dm-core/property/class.rb +17 -0
- data/lib/dm-core/property/date.rb +10 -0
- data/lib/dm-core/property/date_time.rb +10 -0
- data/lib/dm-core/property/decimal.rb +36 -0
- data/lib/dm-core/property/discriminator.rb +44 -0
- data/lib/dm-core/property/float.rb +16 -0
- data/lib/dm-core/property/integer.rb +22 -0
- data/lib/dm-core/property/invalid_value_error.rb +22 -0
- data/lib/dm-core/property/lookup.rb +27 -0
- data/lib/dm-core/property/numeric.rb +38 -0
- data/lib/dm-core/property/object.rb +34 -0
- data/lib/dm-core/property/serial.rb +14 -0
- data/lib/dm-core/property/string.rb +38 -0
- data/lib/dm-core/property/text.rb +9 -0
- data/lib/dm-core/property/time.rb +10 -0
- data/lib/dm-core/property_set.rb +177 -0
- data/lib/dm-core/query.rb +1366 -0
- data/lib/dm-core/query/conditions/comparison.rb +911 -0
- data/lib/dm-core/query/conditions/operation.rb +721 -0
- data/lib/dm-core/query/direction.rb +36 -0
- data/lib/dm-core/query/operator.rb +35 -0
- data/lib/dm-core/query/path.rb +114 -0
- data/lib/dm-core/query/sort.rb +39 -0
- data/lib/dm-core/relationship_set.rb +72 -0
- data/lib/dm-core/repository.rb +226 -0
- data/lib/dm-core/resource.rb +1214 -0
- data/lib/dm-core/resource/persistence_state.rb +75 -0
- data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
- data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
- data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
- data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
- data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
- data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
- data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -0
- data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
- data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
- data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
- data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
- data/lib/dm-core/spec/setup.rb +174 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
- data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
- data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -0
- data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
- data/lib/dm-core/support/assertions.rb +8 -0
- data/lib/dm-core/support/chainable.rb +18 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/descendant_set.rb +89 -0
- data/lib/dm-core/support/equalizer.rb +48 -0
- data/lib/dm-core/support/ext/array.rb +22 -0
- data/lib/dm-core/support/ext/blank.rb +25 -0
- data/lib/dm-core/support/ext/hash.rb +67 -0
- data/lib/dm-core/support/ext/module.rb +47 -0
- data/lib/dm-core/support/ext/object.rb +57 -0
- data/lib/dm-core/support/ext/string.rb +24 -0
- data/lib/dm-core/support/ext/try_dup.rb +12 -0
- data/lib/dm-core/support/hook.rb +405 -0
- data/lib/dm-core/support/inflections.rb +60 -0
- data/lib/dm-core/support/inflector/inflections.rb +211 -0
- data/lib/dm-core/support/inflector/methods.rb +151 -0
- data/lib/dm-core/support/lazy_array.rb +451 -0
- data/lib/dm-core/support/local_object_space.rb +13 -0
- data/lib/dm-core/support/logger.rb +201 -0
- data/lib/dm-core/support/mash.rb +176 -0
- data/lib/dm-core/support/naming_conventions.rb +90 -0
- data/lib/dm-core/support/ordered_set.rb +380 -0
- data/lib/dm-core/support/subject.rb +33 -0
- data/lib/dm-core/support/subject_set.rb +250 -0
- data/lib/dm-core/version.rb +3 -0
- data/script/performance.rb +275 -0
- data/script/profile.rb +218 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +68 -0
- data/spec/public/associations/many_to_many_spec.rb +197 -0
- data/spec/public/associations/many_to_one_spec.rb +83 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
- data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
- data/spec/public/associations/one_to_many_spec.rb +81 -0
- data/spec/public/associations/one_to_one_spec.rb +176 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
- data/spec/public/collection_spec.rb +69 -0
- data/spec/public/finalize_spec.rb +76 -0
- data/spec/public/model/hook_spec.rb +246 -0
- data/spec/public/model/property_spec.rb +88 -0
- data/spec/public/model/relationship_spec.rb +1040 -0
- data/spec/public/model_spec.rb +462 -0
- data/spec/public/property/binary_spec.rb +41 -0
- data/spec/public/property/boolean_spec.rb +22 -0
- data/spec/public/property/class_spec.rb +28 -0
- data/spec/public/property/date_spec.rb +22 -0
- data/spec/public/property/date_time_spec.rb +22 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +135 -0
- data/spec/public/property/float_spec.rb +22 -0
- data/spec/public/property/integer_spec.rb +22 -0
- data/spec/public/property/object_spec.rb +107 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +22 -0
- data/spec/public/property/text_spec.rb +63 -0
- data/spec/public/property/time_spec.rb +22 -0
- data/spec/public/property_spec.rb +341 -0
- data/spec/public/resource_spec.rb +288 -0
- data/spec/public/sel_spec.rb +53 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +309 -0
- data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
- data/spec/public/shared/collection_shared_spec.rb +1667 -0
- data/spec/public/shared/finder_shared_spec.rb +1629 -0
- data/spec/rcov.opts +6 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
- data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +200 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +110 -0
- data/spec/semipublic/model_spec.rb +96 -0
- data/spec/semipublic/property/binary_spec.rb +13 -0
- data/spec/semipublic/property/boolean_spec.rb +47 -0
- data/spec/semipublic/property/class_spec.rb +33 -0
- data/spec/semipublic/property/date_spec.rb +43 -0
- data/spec/semipublic/property/date_time_spec.rb +46 -0
- data/spec/semipublic/property/decimal_spec.rb +83 -0
- data/spec/semipublic/property/discriminator_spec.rb +19 -0
- data/spec/semipublic/property/float_spec.rb +82 -0
- data/spec/semipublic/property/integer_spec.rb +82 -0
- data/spec/semipublic/property/lookup_spec.rb +29 -0
- data/spec/semipublic/property/serial_spec.rb +13 -0
- data/spec/semipublic/property/string_spec.rb +13 -0
- data/spec/semipublic/property/text_spec.rb +31 -0
- data/spec/semipublic/property/time_spec.rb +50 -0
- data/spec/semipublic/property_spec.rb +114 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +1501 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
- data/spec/semipublic/query/path_spec.rb +471 -0
- data/spec/semipublic/query_spec.rb +3682 -0
- data/spec/semipublic/resource/state/clean_spec.rb +88 -0
- data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
- data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
- data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
- data/spec/semipublic/resource/state/transient_spec.rb +162 -0
- data/spec/semipublic/resource/state_spec.rb +230 -0
- data/spec/semipublic/resource_spec.rb +23 -0
- data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +199 -0
- data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
- data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/core_ext/hash.rb +10 -0
- data/spec/support/core_ext/inheritable_attributes.rb +46 -0
- data/spec/support/properties/huge_integer.rb +17 -0
- data/spec/unit/array_spec.rb +23 -0
- data/spec/unit/blank_spec.rb +73 -0
- data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
- data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
- data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
- data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
- data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
- data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
- data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
- data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
- data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
- data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
- data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
- data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
- data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
- data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
- data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
- data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
- data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
- data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
- data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
- data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
- data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
- data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
- data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
- data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
- data/spec/unit/hash_spec.rb +28 -0
- data/spec/unit/hook_spec.rb +1235 -0
- data/spec/unit/inflections_spec.rb +16 -0
- data/spec/unit/lazy_array_spec.rb +1949 -0
- data/spec/unit/mash_spec.rb +312 -0
- data/spec/unit/module_spec.rb +71 -0
- data/spec/unit/object_spec.rb +38 -0
- data/spec/unit/try_dup_spec.rb +46 -0
- data/tasks/ci.rake +1 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +365 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Resource
|
|
3
|
+
|
|
4
|
+
# the state of the resource (abstract)
|
|
5
|
+
class PersistenceState
|
|
6
|
+
extend Equalizer
|
|
7
|
+
|
|
8
|
+
equalize :resource
|
|
9
|
+
|
|
10
|
+
attr_reader :resource
|
|
11
|
+
|
|
12
|
+
def initialize(resource)
|
|
13
|
+
@resource = resource
|
|
14
|
+
@model = resource.model
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get(subject, *args)
|
|
18
|
+
subject.get(resource, *args)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def set(subject, value)
|
|
22
|
+
subject.set(resource, value)
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def delete
|
|
27
|
+
raise NotImplementedError, "#{self.class}#delete should be implemented"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def commit
|
|
31
|
+
raise NotImplementedError, "#{self.class}#commit should be implemented"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def rollback
|
|
35
|
+
raise NotImplementedError, "#{self.class}#rollback should be implemented"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
attr_reader :model
|
|
41
|
+
|
|
42
|
+
def properties
|
|
43
|
+
@properties ||= model.properties(repository.name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def relationships
|
|
47
|
+
@relationships ||= model.relationships(repository.name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def identity_map
|
|
51
|
+
@identity_map ||= repository.identity_map(model)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def remove_from_identity_map
|
|
55
|
+
identity_map.delete(resource.key)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def add_to_identity_map
|
|
59
|
+
identity_map[resource.key] = resource
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def set_child_keys
|
|
63
|
+
relationships.each do |relationship|
|
|
64
|
+
set_child_key(relationship)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def set_child_key(relationship)
|
|
69
|
+
return unless relationship.loaded?(resource) && relationship.respond_to?(:resource_for)
|
|
70
|
+
set(relationship, get(relationship))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end # class PersistenceState
|
|
74
|
+
end # module Resource
|
|
75
|
+
end # module DataMapper
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Resource
|
|
3
|
+
class PersistenceState
|
|
4
|
+
|
|
5
|
+
# a persisted/unmodified resource
|
|
6
|
+
class Clean < Persisted
|
|
7
|
+
def set(subject, value)
|
|
8
|
+
if not_modified?(subject, value)
|
|
9
|
+
self
|
|
10
|
+
else
|
|
11
|
+
# assign to persistence_state so that if Dirty#set calls
|
|
12
|
+
# a Relationship#set, which modifies a Property, the same
|
|
13
|
+
# Dirty state instance will be reused.
|
|
14
|
+
state = resource.persistence_state = Dirty.new(resource)
|
|
15
|
+
state.set(subject, value)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete
|
|
20
|
+
Deleted.new(resource)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def commit
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def rollback
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def not_modified?(subject, value)
|
|
34
|
+
subject.loaded?(resource) && subject.get!(resource).eql?(value)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end # class Clean
|
|
38
|
+
end # class PersistenceState
|
|
39
|
+
end # module Resource
|
|
40
|
+
end # module DataMapper
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Resource
|
|
3
|
+
class PersistenceState
|
|
4
|
+
|
|
5
|
+
# a persisted/deleted resource
|
|
6
|
+
class Deleted < Persisted
|
|
7
|
+
def set(subject, value)
|
|
8
|
+
raise ImmutableDeletedError, 'Deleted resource cannot be modified'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def delete
|
|
12
|
+
self
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def commit
|
|
16
|
+
delete_resource
|
|
17
|
+
remove_from_identity_map
|
|
18
|
+
Immutable.new(resource)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def delete_resource
|
|
24
|
+
repository.delete(collection_for_self)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end # class Deleted
|
|
28
|
+
end # class PersistenceState
|
|
29
|
+
end # module Resource
|
|
30
|
+
end # module DataMapper
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Resource
|
|
3
|
+
class PersistenceState
|
|
4
|
+
|
|
5
|
+
# a persisted/dirty resource
|
|
6
|
+
class Dirty < Persisted
|
|
7
|
+
def set(subject, value)
|
|
8
|
+
track(subject, value)
|
|
9
|
+
super
|
|
10
|
+
original_attributes.empty? ? Clean.new(resource) : self
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def delete
|
|
14
|
+
reset_resource
|
|
15
|
+
Deleted.new(resource)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def commit
|
|
19
|
+
remove_from_identity_map
|
|
20
|
+
set_child_keys
|
|
21
|
+
assert_valid_attributes
|
|
22
|
+
update_resource
|
|
23
|
+
reset_original_attributes
|
|
24
|
+
reset_resource_key
|
|
25
|
+
Clean.new(resource)
|
|
26
|
+
ensure
|
|
27
|
+
add_to_identity_map
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def rollback
|
|
31
|
+
reset_resource
|
|
32
|
+
Clean.new(resource)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def original_attributes
|
|
36
|
+
@original_attributes ||= {}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def track(subject, value)
|
|
42
|
+
if original_attributes.key?(subject)
|
|
43
|
+
# stop tracking if the new value is the same as the original
|
|
44
|
+
if original_attributes[subject].eql?(value)
|
|
45
|
+
original_attributes.delete(subject)
|
|
46
|
+
end
|
|
47
|
+
elsif !value.eql?(original = get(subject))
|
|
48
|
+
# track the original value
|
|
49
|
+
original_attributes[subject] = original
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def update_resource
|
|
54
|
+
repository.update(resource.dirty_attributes, collection_for_self)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def reset_resource
|
|
58
|
+
reset_resource_properties
|
|
59
|
+
reset_resource_relationships
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def reset_resource_key
|
|
63
|
+
resource.instance_eval { remove_instance_variable(:@_key) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def reset_resource_properties
|
|
67
|
+
# delete every original attribute after resetting the resource
|
|
68
|
+
original_attributes.delete_if do |property, value|
|
|
69
|
+
property.set!(resource, value)
|
|
70
|
+
true
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def reset_resource_relationships
|
|
75
|
+
relationships.each do |relationship|
|
|
76
|
+
next unless relationship.loaded?(resource)
|
|
77
|
+
# TODO: consider a method in Relationship that can reset the relationship
|
|
78
|
+
resource.instance_eval { remove_instance_variable(relationship.instance_variable_name) }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def reset_original_attributes
|
|
83
|
+
original_attributes.clear
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def assert_valid_attributes
|
|
87
|
+
properties.each do |property|
|
|
88
|
+
value = property.get! resource
|
|
89
|
+
property.assert_valid_value(value)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end # class Dirty
|
|
94
|
+
end # class PersistenceState
|
|
95
|
+
end # module Resource
|
|
96
|
+
end # module DataMapper
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Resource
|
|
3
|
+
class PersistenceState
|
|
4
|
+
|
|
5
|
+
# a not-persisted/unmodifiable resource
|
|
6
|
+
class Immutable < PersistenceState
|
|
7
|
+
def get(subject, *args)
|
|
8
|
+
unless subject.loaded?(resource) || subject.kind_of?(Associations::Relationship)
|
|
9
|
+
raise ImmutableError, 'Immutable resource cannot be lazy loaded'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def set(subject, value)
|
|
16
|
+
raise ImmutableError, 'Immutable resource cannot be modified'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete
|
|
20
|
+
raise ImmutableError, 'Immutable resource cannot be deleted'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def commit
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def rollback
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end # class Immutable
|
|
32
|
+
end # class PersistenceState
|
|
33
|
+
end # module Resource
|
|
34
|
+
end # module DataMapper
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Resource
|
|
3
|
+
class PersistenceState
|
|
4
|
+
|
|
5
|
+
# a persisted resource (abstract)
|
|
6
|
+
class Persisted < PersistenceState
|
|
7
|
+
def get(subject, *args)
|
|
8
|
+
lazy_load(subject)
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def repository
|
|
15
|
+
@repository ||= resource.instance_variable_get(:@_repository)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def collection_for_self
|
|
19
|
+
@collection_for_self ||= resource.collection_for_self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def lazy_load(subject)
|
|
23
|
+
subject.lazy_load(resource)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end # class Persisted
|
|
27
|
+
end # class PersistenceState
|
|
28
|
+
end # module Resource
|
|
29
|
+
end # module DataMapper
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Resource
|
|
3
|
+
class PersistenceState
|
|
4
|
+
|
|
5
|
+
# a not-persisted/modifiable resource
|
|
6
|
+
class Transient < PersistenceState
|
|
7
|
+
def get(subject, *args)
|
|
8
|
+
set_default_value(subject)
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def set(subject, value)
|
|
13
|
+
track(subject)
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def delete
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def commit
|
|
22
|
+
set_child_keys
|
|
23
|
+
set_default_values
|
|
24
|
+
assert_valid_attributes
|
|
25
|
+
create_resource
|
|
26
|
+
set_repository
|
|
27
|
+
add_to_identity_map
|
|
28
|
+
Clean.new(resource)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def rollback
|
|
32
|
+
self
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def original_attributes
|
|
36
|
+
@original_attributes ||= {}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def repository
|
|
42
|
+
@repository ||= model.repository
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def set_default_values
|
|
46
|
+
(properties | relationships).each do |subject|
|
|
47
|
+
set_default_value(subject)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def set_default_value(subject)
|
|
52
|
+
return if subject.loaded?(resource) || !subject.default?
|
|
53
|
+
set(subject, subject.default_for(resource))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def track(subject)
|
|
57
|
+
original_attributes[subject] = nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def create_resource
|
|
61
|
+
repository.create([ resource ])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def set_repository
|
|
65
|
+
resource.instance_variable_set(:@_repository, repository)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def assert_valid_attributes
|
|
69
|
+
properties.each do |property|
|
|
70
|
+
value = get(property)
|
|
71
|
+
unless property.serial? && value.nil?
|
|
72
|
+
property.assert_valid_value(value)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end # class Transient
|
|
78
|
+
end # class PersistenceState
|
|
79
|
+
end # module Resource
|
|
80
|
+
end # module DataMapper
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Spec
|
|
3
|
+
module Adapters
|
|
4
|
+
|
|
5
|
+
module Helpers
|
|
6
|
+
|
|
7
|
+
def supported_by(*adapters, &block)
|
|
8
|
+
adapters = adapters.map { |adapter| adapter.to_sym }
|
|
9
|
+
adapter = DataMapper::Spec.adapter_name.to_sym
|
|
10
|
+
if adapters.include?(:all) || adapters.include?(adapter)
|
|
11
|
+
describe_adapter(:default, &block)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def with_alternate_adapter(&block)
|
|
16
|
+
describe_adapter(:alternate, &block)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def describe_adapter(kind, &block)
|
|
20
|
+
describe("with #{kind} adapter") do
|
|
21
|
+
|
|
22
|
+
before :all do
|
|
23
|
+
# store these in instance vars for the shared adapter specs
|
|
24
|
+
@adapter = DataMapper::Spec.adapter(kind)
|
|
25
|
+
@repository = DataMapper.repository(@adapter.name)
|
|
26
|
+
|
|
27
|
+
@repository.scope { DataMapper.finalize }
|
|
28
|
+
|
|
29
|
+
# create all tables and constraints before each spec
|
|
30
|
+
DataMapper::Model.descendants.each do |model|
|
|
31
|
+
next unless model.respond_to?(:auto_migrate!)
|
|
32
|
+
begin
|
|
33
|
+
model.auto_migrate!(@repository.name)
|
|
34
|
+
rescue IncompleteModelError
|
|
35
|
+
# skip incomplete models
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
after :all do
|
|
41
|
+
# remove all tables and constraints after each spec
|
|
42
|
+
DataMapper::Model.descendants.each do |model|
|
|
43
|
+
next unless model.respond_to?(:auto_migrate_down!)
|
|
44
|
+
begin
|
|
45
|
+
model.auto_migrate_down!(@repository.name)
|
|
46
|
+
rescue IncompleteModelError
|
|
47
|
+
# skip incomplete models
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
# TODO consider proper automigrate functionality
|
|
51
|
+
if @adapter.respond_to?(:reset)
|
|
52
|
+
@adapter.reset
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
instance_eval(&block)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|