datamapper-dm-core 0.9.11 → 0.10.0

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