datamapper-dm-core 0.9.11 → 0.10.0

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 (192) hide show
  1. data/.autotest +17 -14
  2. data/.gitignore +3 -1
  3. data/FAQ +6 -5
  4. data/History.txt +5 -39
  5. data/Manifest.txt +67 -76
  6. data/QUICKLINKS +1 -1
  7. data/README.txt +21 -15
  8. data/Rakefile +16 -15
  9. data/SPECS +2 -29
  10. data/TODO +1 -1
  11. data/dm-core.gemspec +11 -15
  12. data/lib/dm-core/adapters/abstract_adapter.rb +182 -185
  13. data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
  14. data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
  15. data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
  16. data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
  17. data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
  18. data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
  19. data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
  20. data/lib/dm-core/adapters.rb +135 -16
  21. data/lib/dm-core/associations/many_to_many.rb +372 -90
  22. data/lib/dm-core/associations/many_to_one.rb +220 -73
  23. data/lib/dm-core/associations/one_to_many.rb +319 -255
  24. data/lib/dm-core/associations/one_to_one.rb +66 -53
  25. data/lib/dm-core/associations/relationship.rb +560 -158
  26. data/lib/dm-core/collection.rb +1104 -381
  27. data/lib/dm-core/core_ext/kernel.rb +12 -0
  28. data/lib/dm-core/core_ext/symbol.rb +10 -0
  29. data/lib/dm-core/identity_map.rb +4 -34
  30. data/lib/dm-core/migrations.rb +1283 -0
  31. data/lib/dm-core/model/descendant_set.rb +81 -0
  32. data/lib/dm-core/model/hook.rb +45 -0
  33. data/lib/dm-core/model/is.rb +32 -0
  34. data/lib/dm-core/model/property.rb +248 -0
  35. data/lib/dm-core/model/relationship.rb +335 -0
  36. data/lib/dm-core/model/scope.rb +90 -0
  37. data/lib/dm-core/model.rb +570 -369
  38. data/lib/dm-core/property.rb +753 -280
  39. data/lib/dm-core/property_set.rb +141 -98
  40. data/lib/dm-core/query/conditions/comparison.rb +814 -0
  41. data/lib/dm-core/query/conditions/operation.rb +247 -0
  42. data/lib/dm-core/query/direction.rb +43 -0
  43. data/lib/dm-core/query/operator.rb +42 -0
  44. data/lib/dm-core/query/path.rb +102 -0
  45. data/lib/dm-core/query/sort.rb +45 -0
  46. data/lib/dm-core/query.rb +974 -492
  47. data/lib/dm-core/repository.rb +147 -107
  48. data/lib/dm-core/resource.rb +644 -429
  49. data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
  50. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
  51. data/lib/dm-core/support/chainable.rb +20 -0
  52. data/lib/dm-core/support/deprecate.rb +12 -0
  53. data/lib/dm-core/support/equalizer.rb +23 -0
  54. data/lib/dm-core/support/logger.rb +13 -0
  55. data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
  56. data/lib/dm-core/transaction.rb +333 -92
  57. data/lib/dm-core/type.rb +98 -60
  58. data/lib/dm-core/types/boolean.rb +1 -1
  59. data/lib/dm-core/types/discriminator.rb +34 -20
  60. data/lib/dm-core/types/object.rb +7 -4
  61. data/lib/dm-core/types/paranoid_boolean.rb +11 -9
  62. data/lib/dm-core/types/paranoid_datetime.rb +11 -9
  63. data/lib/dm-core/types/serial.rb +3 -3
  64. data/lib/dm-core/types/text.rb +3 -4
  65. data/lib/dm-core/version.rb +1 -1
  66. data/lib/dm-core.rb +106 -110
  67. data/script/performance.rb +102 -109
  68. data/script/profile.rb +169 -38
  69. data/spec/lib/adapter_helpers.rb +105 -0
  70. data/spec/lib/collection_helpers.rb +18 -0
  71. data/spec/lib/counter_adapter.rb +34 -0
  72. data/spec/lib/pending_helpers.rb +27 -0
  73. data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
  74. data/spec/public/associations/many_to_many_spec.rb +193 -0
  75. data/spec/public/associations/many_to_one_spec.rb +73 -0
  76. data/spec/public/associations/one_to_many_spec.rb +77 -0
  77. data/spec/public/associations/one_to_one_spec.rb +156 -0
  78. data/spec/public/collection_spec.rb +65 -0
  79. data/spec/public/model/relationship_spec.rb +924 -0
  80. data/spec/public/model_spec.rb +159 -0
  81. data/spec/public/property_spec.rb +829 -0
  82. data/spec/public/resource_spec.rb +71 -0
  83. data/spec/public/sel_spec.rb +44 -0
  84. data/spec/public/setup_spec.rb +145 -0
  85. data/spec/public/shared/association_collection_shared_spec.rb +317 -0
  86. data/spec/public/shared/collection_shared_spec.rb +1723 -0
  87. data/spec/public/shared/finder_shared_spec.rb +1619 -0
  88. data/spec/public/shared/resource_shared_spec.rb +924 -0
  89. data/spec/public/shared/sel_shared_spec.rb +112 -0
  90. data/spec/public/transaction_spec.rb +129 -0
  91. data/spec/public/types/discriminator_spec.rb +130 -0
  92. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  93. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
  94. data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
  95. data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
  96. data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
  97. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
  98. data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
  99. data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
  100. data/spec/semipublic/associations/relationship_spec.rb +194 -0
  101. data/spec/semipublic/associations_spec.rb +177 -0
  102. data/spec/semipublic/collection_spec.rb +142 -0
  103. data/spec/semipublic/property_spec.rb +61 -0
  104. data/spec/semipublic/query/conditions_spec.rb +528 -0
  105. data/spec/semipublic/query/path_spec.rb +443 -0
  106. data/spec/semipublic/query_spec.rb +2626 -0
  107. data/spec/semipublic/resource_spec.rb +47 -0
  108. data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
  109. data/spec/spec.opts +3 -1
  110. data/spec/spec_helper.rb +80 -57
  111. data/tasks/ci.rb +19 -31
  112. data/tasks/dm.rb +43 -48
  113. data/tasks/doc.rb +8 -11
  114. data/tasks/gemspec.rb +5 -5
  115. data/tasks/hoe.rb +15 -16
  116. data/tasks/install.rb +8 -10
  117. metadata +72 -93
  118. data/lib/dm-core/associations/relationship_chain.rb +0 -81
  119. data/lib/dm-core/associations.rb +0 -207
  120. data/lib/dm-core/auto_migrations.rb +0 -105
  121. data/lib/dm-core/dependency_queue.rb +0 -32
  122. data/lib/dm-core/hook.rb +0 -11
  123. data/lib/dm-core/is.rb +0 -16
  124. data/lib/dm-core/logger.rb +0 -232
  125. data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
  126. data/lib/dm-core/migrator.rb +0 -29
  127. data/lib/dm-core/scope.rb +0 -58
  128. data/lib/dm-core/support/array.rb +0 -13
  129. data/lib/dm-core/support/assertions.rb +0 -8
  130. data/lib/dm-core/support/errors.rb +0 -23
  131. data/lib/dm-core/support/kernel.rb +0 -11
  132. data/lib/dm-core/support/symbol.rb +0 -41
  133. data/lib/dm-core/support.rb +0 -7
  134. data/lib/dm-core/type_map.rb +0 -80
  135. data/lib/dm-core/types.rb +0 -19
  136. data/script/all +0 -4
  137. data/spec/integration/association_spec.rb +0 -1382
  138. data/spec/integration/association_through_spec.rb +0 -203
  139. data/spec/integration/associations/many_to_many_spec.rb +0 -449
  140. data/spec/integration/associations/many_to_one_spec.rb +0 -163
  141. data/spec/integration/associations/one_to_many_spec.rb +0 -188
  142. data/spec/integration/auto_migrations_spec.rb +0 -413
  143. data/spec/integration/collection_spec.rb +0 -1073
  144. data/spec/integration/data_objects_adapter_spec.rb +0 -32
  145. data/spec/integration/dependency_queue_spec.rb +0 -46
  146. data/spec/integration/model_spec.rb +0 -197
  147. data/spec/integration/mysql_adapter_spec.rb +0 -85
  148. data/spec/integration/postgres_adapter_spec.rb +0 -731
  149. data/spec/integration/property_spec.rb +0 -253
  150. data/spec/integration/query_spec.rb +0 -514
  151. data/spec/integration/repository_spec.rb +0 -61
  152. data/spec/integration/resource_spec.rb +0 -513
  153. data/spec/integration/sqlite3_adapter_spec.rb +0 -352
  154. data/spec/integration/sti_spec.rb +0 -273
  155. data/spec/integration/strategic_eager_loading_spec.rb +0 -156
  156. data/spec/integration/transaction_spec.rb +0 -75
  157. data/spec/integration/type_spec.rb +0 -275
  158. data/spec/lib/logging_helper.rb +0 -18
  159. data/spec/lib/mock_adapter.rb +0 -27
  160. data/spec/lib/model_loader.rb +0 -100
  161. data/spec/lib/publicize_methods.rb +0 -28
  162. data/spec/models/content.rb +0 -16
  163. data/spec/models/vehicles.rb +0 -34
  164. data/spec/models/zoo.rb +0 -48
  165. data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
  166. data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
  167. data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
  168. data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
  169. data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
  170. data/spec/unit/associations/many_to_many_spec.rb +0 -32
  171. data/spec/unit/associations/many_to_one_spec.rb +0 -159
  172. data/spec/unit/associations/one_to_many_spec.rb +0 -393
  173. data/spec/unit/associations/one_to_one_spec.rb +0 -7
  174. data/spec/unit/associations/relationship_spec.rb +0 -71
  175. data/spec/unit/associations_spec.rb +0 -242
  176. data/spec/unit/auto_migrations_spec.rb +0 -111
  177. data/spec/unit/collection_spec.rb +0 -182
  178. data/spec/unit/data_mapper_spec.rb +0 -35
  179. data/spec/unit/identity_map_spec.rb +0 -126
  180. data/spec/unit/is_spec.rb +0 -80
  181. data/spec/unit/migrator_spec.rb +0 -33
  182. data/spec/unit/model_spec.rb +0 -321
  183. data/spec/unit/naming_conventions_spec.rb +0 -36
  184. data/spec/unit/property_set_spec.rb +0 -90
  185. data/spec/unit/property_spec.rb +0 -753
  186. data/spec/unit/query_spec.rb +0 -571
  187. data/spec/unit/repository_spec.rb +0 -93
  188. data/spec/unit/resource_spec.rb +0 -649
  189. data/spec/unit/scope_spec.rb +0 -142
  190. data/spec/unit/transaction_spec.rb +0 -493
  191. data/spec/unit/type_map_spec.rb +0 -114
  192. data/spec/unit/type_spec.rb +0 -119
@@ -1,169 +1,212 @@
1
1
  module DataMapper
2
- class PropertySet
3
- include Assertions
4
- include Enumerable
5
-
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 < Array
7
+ extend Deprecate
8
+
9
+ deprecate :has_property?, :named?
10
+ deprecate :slice, :values_at
11
+ deprecate :add, :<<
12
+
13
+ # TODO: document
14
+ # @api semipublic
6
15
  def [](name)
7
- property_for(name) || raise(ArgumentError, "Unknown property '#{name}'", caller)
16
+ @properties[name]
8
17
  end
9
18
 
19
+ alias super_slice []=
20
+
21
+ # TODO: document
22
+ # @api semipublic
10
23
  def []=(name, property)
11
- @key, @defaults = nil
12
- if existing_property = detect { |p| p.name == name }
13
- property.hash
14
- @entries[@entries.index(existing_property)] = property
24
+ if named?(name)
25
+ add_property(property)
26
+ super_slice(index(property), property)
15
27
  else
16
- add(property)
28
+ self << property
17
29
  end
18
- property
19
- end
20
-
21
- def has_property?(name)
22
- !!property_for(name)
23
- end
24
-
25
- def slice(*names)
26
- @key, @defaults = nil
27
- names.map do |name|
28
- property_for(name)
29
- end
30
- end
31
-
32
- def clear
33
- @key, @defaults = nil
34
- @entries.clear
35
30
  end
36
31
 
37
- def add(*properties)
38
- @key, @defaults = nil
39
- @entries.push(*properties)
40
- properties.each { |property| property.hash }
41
- self
32
+ # TODO: document
33
+ # @api semipublic
34
+ def named?(name)
35
+ @properties.key?(name)
42
36
  end
43
37
 
44
- alias << add
45
-
46
- def length
47
- @entries.length
38
+ # TODO: document
39
+ # @api semipublic
40
+ def values_at(*names)
41
+ @properties.values_at(*names)
48
42
  end
49
43
 
50
- def empty?
51
- @entries.empty?
44
+ # TODO: document
45
+ # @api semipublic
46
+ def <<(property)
47
+ if named?(property.name)
48
+ add_property(property)
49
+ super_slice(index(property), property)
50
+ else
51
+ add_property(property)
52
+ super
53
+ end
52
54
  end
53
55
 
54
- def each
55
- @entries.each { |property| yield property }
56
- self
56
+ # TODO: document
57
+ # @api semipublic
58
+ def include?(property)
59
+ named?(property.name)
57
60
  end
58
61
 
62
+ # TODO: make PropertySet#reject return a PropertySet instance
63
+ # TODO: document
64
+ # @api semipublic
59
65
  def defaults
60
- @defaults ||= reject { |property| property.lazy? }
66
+ @defaults ||= self.class.new(key | [ discriminator ].compact | reject { |property| property.lazy? }).freeze
61
67
  end
62
68
 
69
+ # TODO: document
70
+ # @api semipublic
63
71
  def key
64
- @key ||= select { |property| property.key? }
72
+ @key ||= self.class.new(select { |property| property.key? }).freeze
73
+ end
74
+
75
+ # TODO: document
76
+ # @api semipublic
77
+ def discriminator
78
+ @discriminator ||= detect { |property| property.type == Types::Discriminator }
65
79
  end
66
80
 
81
+ # TODO: document
82
+ # @api semipublic
67
83
  def indexes
68
84
  index_hash = {}
69
- repository_name = repository.name
70
- each { |property| parse_index(property.index, property.field(repository_name), index_hash) }
85
+ each { |property| parse_index(property.index, property.field, index_hash) }
71
86
  index_hash
72
87
  end
73
88
 
89
+ # TODO: document
90
+ # @api semipublic
74
91
  def unique_indexes
75
92
  index_hash = {}
76
- repository_name = repository.name
77
- each { |property| parse_index(property.unique_index, property.field(repository_name), index_hash) }
93
+ each { |property| parse_index(property.unique_index, property.field, index_hash) }
78
94
  index_hash
79
95
  end
80
96
 
97
+ # TODO: document
98
+ # @api semipublic
81
99
  def get(resource)
82
100
  map { |property| property.get(resource) }
83
101
  end
84
102
 
103
+ # TODO: document
104
+ # @api semipublic
105
+ def get!(resource)
106
+ map { |property| property.get!(resource) }
107
+ end
108
+
109
+ # TODO: document
110
+ # @api semipublic
85
111
  def set(resource, values)
86
- if values.kind_of?(Array) && values.length != length
87
- raise ArgumentError, "+values+ must have a length of #{length}, but has #{values.length}", caller
88
- end
112
+ zip(values) { |property, value| property.set(resource, value) }
113
+ end
89
114
 
90
- each_with_index { |property,i| property.set(resource, values.nil? ? nil : values[i]) }
115
+ # TODO: document
116
+ # @api semipublic
117
+ def set!(resource, values)
118
+ zip(values) { |property, value| property.set!(resource, value) }
91
119
  end
92
120
 
93
- def property_contexts(name)
94
- contexts = []
95
- lazy_contexts.each do |context,property_names|
96
- contexts << context if property_names.include?(name)
97
- end
98
- contexts
121
+ # TODO: document
122
+ # @api semipublic
123
+ def loaded?(resource)
124
+ all? { |property| property.loaded?(resource) }
99
125
  end
100
126
 
101
- def lazy_context(name)
102
- lazy_contexts[name] ||= []
127
+ # TODO: document
128
+ # @api semipublic
129
+ def typecast(values)
130
+ zip(values.nil? ? [] : values).map { |property, value| property.typecast(value) }
103
131
  end
104
132
 
105
- def lazy_load_context(names)
106
- if names.kind_of?(Array) && names.empty?
107
- raise ArgumentError, '+names+ cannot be empty', caller
133
+ # TODO: document
134
+ # @api private
135
+ def property_contexts(property)
136
+ contexts = []
137
+ lazy_contexts.each do |context, properties|
138
+ contexts << context if properties.include?(property)
108
139
  end
140
+ contexts
141
+ end
109
142
 
110
- result = []
143
+ # TODO: document
144
+ # @api private
145
+ def lazy_context(context)
146
+ lazy_contexts[context] ||= []
147
+ end
111
148
 
112
- Array(names).each do |name|
113
- contexts = property_contexts(name)
114
- if contexts.empty?
115
- result << name # not lazy
149
+ # TODO: document
150
+ # @api private
151
+ def in_context(properties)
152
+ properties_in_context = properties.map do |property|
153
+ if (contexts = property_contexts(property)).any?
154
+ lazy_contexts.values_at(*contexts)
116
155
  else
117
- result |= lazy_contexts.values_at(*contexts).flatten.uniq
156
+ property
118
157
  end
119
158
  end
120
- result
121
- end
122
159
 
123
- def to_query(bind_values)
124
- Hash[ *zip(bind_values).flatten ]
125
- end
126
-
127
- def inspect
128
- '#<PropertySet:{' + map { |property| property.inspect }.join(',') + '}>'
160
+ properties_in_context.flatten.uniq
129
161
  end
130
162
 
131
163
  private
132
164
 
133
- def initialize(properties = [])
134
- assert_kind_of 'properties', properties, Enumerable
165
+ # TODO: document
166
+ # @api semipublic
167
+ def initialize(*)
168
+ super
169
+ @properties = map { |property| [ property.name, property ] }.to_mash
170
+ end
171
+
172
+ # TODO: document
173
+ # @api private
174
+ def initialize_copy(*)
175
+ super
176
+ @properties = @properties.dup
177
+ end
135
178
 
136
- @entries = properties
137
- @property_for = {}
179
+ # TODO: document
180
+ # @api private
181
+ def add_property(property)
182
+ clear_cache
183
+ @properties[property.name] = property
138
184
  end
139
185
 
140
- def initialize_copy(orig)
141
- @key, @defaults = nil
142
- @entries = orig.entries.dup
143
- @property_for = {}
186
+ # TODO: document
187
+ # @api private
188
+ def clear_cache
189
+ @defaults, @key, @discriminator = nil
144
190
  end
145
191
 
192
+ # TODO: document
193
+ # @api private
146
194
  def lazy_contexts
147
195
  @lazy_contexts ||= {}
148
196
  end
149
197
 
198
+ # TODO: document
199
+ # @api private
150
200
  def parse_index(index, property, index_hash)
151
201
  case index
152
- when true then index_hash[property] = [property]
153
- when Symbol
154
- index_hash[index.to_s] ||= []
155
- index_hash[index.to_s] << property
156
- when Enumerable then index.each { |idx| parse_index(idx, property, index_hash) }
202
+ when true
203
+ index_hash[property] = [ property ]
204
+ when Symbol
205
+ index_hash[index] ||= []
206
+ index_hash[index] << property
207
+ when Array
208
+ index.each { |idx| parse_index(idx, property, index_hash) }
157
209
  end
158
210
  end
159
-
160
- def property_for(name)
161
- unless @property_for[name]
162
- property = detect { |property| property.name == name.to_sym }
163
- @property_for[name.to_s] = @property_for[name.to_sym] = property if property
164
- end
165
- @property_for[name]
166
- end
167
-
168
211
  end # class PropertySet
169
212
  end # module DataMapper