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,514 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
-
3
- if ADAPTER
4
- module QuerySpec
5
- class SailBoat
6
- include DataMapper::Resource
7
-
8
- property :id, Serial
9
- property :name, String
10
- property :port, String
11
- property :captain, String
12
-
13
- def self.default_repository_name
14
- ADAPTER
15
- end
16
- end
17
-
18
- class Permission
19
- include DataMapper::Resource
20
-
21
- property :id, Serial
22
- property :user_id, Integer
23
- property :resource_id, Integer
24
- property :resource_type, String
25
- property :token, String
26
-
27
- def self.default_repository_name
28
- ADAPTER
29
- end
30
- end
31
-
32
- class Region
33
- include DataMapper::Resource
34
-
35
- property :id, Serial
36
- property :name, String
37
- property :type, String
38
-
39
- def self.default_repository_name
40
- ADAPTER
41
- end
42
- end
43
-
44
- class Factory
45
- include DataMapper::Resource
46
-
47
- property :id, Serial
48
- property :region_id, Integer
49
- property :name, String
50
-
51
- repository(:mock) do
52
- property :land, String
53
- end
54
-
55
- belongs_to :region
56
-
57
- def self.default_repository_name
58
- ADAPTER
59
- end
60
- end
61
-
62
- class Vehicle
63
- include DataMapper::Resource
64
-
65
- property :id, Serial
66
- property :factory_id, Integer
67
- property :name, String
68
-
69
- belongs_to :factory
70
-
71
- def self.default_repository_name
72
- ADAPTER
73
- end
74
- end
75
-
76
- class Group
77
- include DataMapper::Resource
78
- property :id, Serial
79
- property :name, String
80
- end
81
- end
82
-
83
- module Namespace
84
- class Region
85
- include DataMapper::Resource
86
-
87
- property :id, Serial
88
- property :name, String
89
-
90
- def self.default_repository_name
91
- ADAPTER
92
- end
93
- end
94
-
95
- class Factory
96
- include DataMapper::Resource
97
-
98
- property :id, Serial
99
- property :region_id, Integer
100
- property :name, String
101
-
102
- repository(:mock) do
103
- property :land, String
104
- end
105
-
106
- belongs_to :region
107
-
108
- def self.default_repository_name
109
- ADAPTER
110
- end
111
- end
112
-
113
- class Vehicle
114
- include DataMapper::Resource
115
- property :id, Serial
116
- property :factory_id, Integer
117
- property :name, String
118
-
119
- belongs_to :factory
120
-
121
- def self.default_repository_name
122
- ADAPTER
123
- end
124
- end
125
- end
126
-
127
- describe DataMapper::Query, "with #{ADAPTER}" do
128
- before do
129
- @query = DataMapper::Query.new(repository(ADAPTER), QuerySpec::SailBoat)
130
- end
131
-
132
- it 'should be serializable with Marshal' do
133
- Marshal.load(Marshal.dump(@query)).should == @query
134
- end
135
-
136
- describe '#unique' do
137
- include LoggingHelper
138
-
139
- before(:each) do
140
- QuerySpec::SailBoat.auto_migrate!
141
-
142
- QuerySpec::SailBoat.create(:name => 'A', :port => 'C')
143
- QuerySpec::SailBoat.create(:name => 'B', :port => 'B')
144
- QuerySpec::SailBoat.create(:name => 'C', :port => 'A')
145
- end
146
-
147
- def parse_statement(log)
148
- log.readlines.join.chomp.split(' ~ ').last.sub(/\A\(\d+\.\d+\)\s+/, '')
149
- end
150
-
151
- describe 'when true' do
152
- if [ :postgres, :sqlite3, :mysql ].include?(ADAPTER)
153
- it 'should add a GROUP BY to the SQL query' do
154
- logger do |log|
155
- QuerySpec::SailBoat.all(:unique => true, :fields => [ :id ]).to_a
156
-
157
- case ADAPTER
158
- when :postgres, :sqlite3
159
- parse_statement(log).should == 'SELECT "id" FROM "query_spec_sail_boats" GROUP BY "id" ORDER BY "id"'
160
- when :mysql
161
- parse_statement(log).should == 'SELECT `id` FROM `query_spec_sail_boats` GROUP BY `id` ORDER BY `id`'
162
- end
163
- end
164
- end
165
-
166
- it 'should not add a GROUP BY to the SQL query if no field is a Property' do
167
- operator = DataMapper::Query::Operator.new(:thing, :test)
168
-
169
- # make the operator act like a Property
170
- class << operator
171
- property = QuerySpec::SailBoat.properties[:id]
172
- (property.methods - (public_instance_methods - %w[ type ])).each do |method|
173
- define_method(method) do |*args|
174
- property.send(method, *args)
175
- end
176
- end
177
- end
178
-
179
- operator.should_not be_kind_of(DataMapper::Property)
180
-
181
- logger do |log|
182
- QuerySpec::SailBoat.all(:unique => true, :fields => [ operator ]).to_a
183
-
184
- case ADAPTER
185
- when :postgres, :sqlite3
186
- parse_statement(log).should == 'SELECT "id" FROM "query_spec_sail_boats" ORDER BY "id"'
187
- when :mysql
188
- parse_statement(log).should == 'SELECT `id` FROM `query_spec_sail_boats` ORDER BY `id`'
189
- end
190
- end
191
- end
192
- end
193
- end
194
-
195
- describe 'when false' do
196
- if [ :postgres, :sqlite3, :mysql ].include?(ADAPTER)
197
- it 'should not add a GROUP BY to the SQL query' do
198
- logger do |log|
199
- QuerySpec::SailBoat.all(:unique => false, :fields => [ :id ]).to_a
200
-
201
- case ADAPTER
202
- when :postgres, :sqlite3
203
- parse_statement(log).should == 'SELECT "id" FROM "query_spec_sail_boats" ORDER BY "id"'
204
- when :mysql
205
- parse_statement(log).should == 'SELECT `id` FROM `query_spec_sail_boats` ORDER BY `id`'
206
- end
207
- end
208
- end
209
- end
210
- end
211
- end
212
-
213
- describe 'when ordering' do
214
- before(:each) do
215
- QuerySpec::SailBoat.auto_migrate!
216
-
217
- QuerySpec::SailBoat.create(:name => 'A', :port => 'C')
218
- QuerySpec::SailBoat.create(:name => 'B', :port => 'B')
219
- QuerySpec::SailBoat.create(:name => 'C', :port => 'A')
220
- end
221
-
222
- it "should find by conditions" do
223
- lambda do
224
- repository(ADAPTER) do
225
- QuerySpec::SailBoat.first(:conditions => [ 'name = ?', 'B' ])
226
- end
227
- end.should_not raise_error
228
-
229
- lambda do
230
- repository(ADAPTER) do
231
- QuerySpec::SailBoat.first(:conditions => [ 'name = ?', 'A' ])
232
- end
233
- end.should_not raise_error
234
- end
235
-
236
- it "should find by conditions passed in as hash" do
237
- repository(ADAPTER) do
238
- QuerySpec::SailBoat.create(:name => "couldbe@email.com", :port => 'wee')
239
-
240
- find = QuerySpec::SailBoat.first(:name => 'couldbe@email.com')
241
- find.name.should == 'couldbe@email.com'
242
-
243
- find = QuerySpec::SailBoat.first(:name => 'couldbe@email.com', :port.not => nil)
244
- find.should_not be_nil
245
- find.port.should_not be_nil
246
- find.name.should == 'couldbe@email.com'
247
- end
248
- end
249
-
250
- it "should find by conditions passed in a range" do
251
- repository(ADAPTER) do
252
- find = QuerySpec::SailBoat.all(:id => 0..2)
253
- find.should_not be_nil
254
- find.should have(2).entries
255
-
256
- find = QuerySpec::SailBoat.all(:id.not => 0..2)
257
- find.should have(1).entries
258
- end
259
- end
260
-
261
- it "should find by conditions passed in as an array" do
262
- repository(ADAPTER) do
263
- find = QuerySpec::SailBoat.all(:id => [1,2])
264
- find.should_not be_nil
265
- find.should have(2).entries
266
-
267
- find = QuerySpec::SailBoat.all(:id.not => [1,2])
268
- find.should have(1).entries
269
- end
270
- end
271
-
272
- describe "conditions passed in as an empty array" do
273
- it "should work when id is an empty Array" do
274
- repository(ADAPTER) do
275
- find = QuerySpec::SailBoat.all(:id => [])
276
- find.should have(0).entries
277
- end
278
- end
279
-
280
- it "should work when id is NOT an empty Array" do
281
- repository(ADAPTER) do
282
- find = QuerySpec::SailBoat.all(:id.not => [])
283
- find.should have(3).entries
284
- end
285
- end
286
-
287
- it "should work when id is an empty Array and other conditions are specified" do
288
- repository(ADAPTER) do
289
- find = QuerySpec::SailBoat.all(:id => [], :name => "A")
290
- find.should have(0).entries
291
- end
292
- end
293
-
294
- it "should work when id is NOT an empty Array and other conditions are specified" do
295
- repository(ADAPTER) do
296
- find = QuerySpec::SailBoat.all(:id.not => [], :name => "A")
297
- find.should have(1).entries
298
- end
299
- end
300
-
301
- it "should work when id is NOT an empty Array and other Array conditions are specified" do
302
- repository(ADAPTER) do
303
- find = QuerySpec::SailBoat.all(:id.not => [], :name => ["A", "B"])
304
- find.should have(2).entries
305
- end
306
- end
307
- end
308
-
309
- it "should order results" do
310
- repository(ADAPTER) do
311
- result = QuerySpec::SailBoat.all(:order => [
312
- DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:name], :asc)
313
- ])
314
- result[0].id.should == 1
315
-
316
- result = QuerySpec::SailBoat.all(:order => [
317
- DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:port], :asc)
318
- ])
319
- result[0].id.should == 3
320
-
321
- result = QuerySpec::SailBoat.all(:order => [
322
- DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:name], :asc),
323
- DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:port], :asc)
324
- ])
325
- result[0].id.should == 1
326
-
327
- result = QuerySpec::SailBoat.all(:order => [
328
- QuerySpec::SailBoat.properties[:name],
329
- DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:port], :asc)
330
- ])
331
- result[0].id.should == 1
332
-
333
- result = QuerySpec::SailBoat.all(:order => [ :name ])
334
- result[0].id.should == 1
335
-
336
- result = QuerySpec::SailBoat.all(:order => [ :name.desc ])
337
- result[0].id.should == 3
338
- end
339
- end
340
- end
341
-
342
- describe 'when sub-selecting' do
343
- before(:each) do
344
- [ QuerySpec::SailBoat, QuerySpec::Permission ].each { |m| m.auto_migrate! }
345
-
346
- QuerySpec::SailBoat.create(:id => 1, :name => "Fantasy I", :port => "Cape Town", :captain => 'Joe')
347
- QuerySpec::SailBoat.create(:id => 2, :name => "Royal Flush II", :port => "Cape Town", :captain => 'James')
348
- QuerySpec::SailBoat.create(:id => 3, :name => "Infringer III", :port => "Cape Town", :captain => 'Jason')
349
-
350
- #User 1 permission -- read boat 1 & 2
351
- QuerySpec::Permission.create(:id => 1, :user_id => 1, :resource_id => 1, :resource_type => 'SailBoat', :token => 'READ')
352
- QuerySpec::Permission.create(:id => 2, :user_id => 1, :resource_id => 2, :resource_type => 'SailBoat', :token => 'READ')
353
-
354
- #User 2 permission -- read boat 2 & 3
355
- QuerySpec::Permission.create(:id => 3, :user_id => 2, :resource_id => 2, :resource_type => 'SailBoat', :token => 'READ')
356
- QuerySpec::Permission.create(:id => 4, :user_id => 2, :resource_id => 3, :resource_type => 'SailBoat', :token => 'READ')
357
- end
358
-
359
- it 'should accept a DM::Query as a value of a condition' do
360
- # User 1
361
- acl = DataMapper::Query.new(repository(ADAPTER), QuerySpec::Permission, :user_id => 1, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
362
- query = { :port => 'Cape Town', :id => acl, :captain.like => 'J%', :order => [ :id ] }
363
- boats = repository(ADAPTER) { QuerySpec::SailBoat.all(query) }
364
- boats.should have(2).entries
365
- boats.entries[0].id.should == 1
366
- boats.entries[1].id.should == 2
367
-
368
- # User 2
369
- acl = DataMapper::Query.new(repository(ADAPTER), QuerySpec::Permission, :user_id => 2, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
370
- query = { :port => 'Cape Town', :id => acl, :captain.like => 'J%', :order => [ :id ] }
371
- boats = repository(ADAPTER) { QuerySpec::SailBoat.all(query) }
372
-
373
- boats.should have(2).entries
374
- boats.entries[0].id.should == 2
375
- boats.entries[1].id.should == 3
376
- end
377
-
378
- it 'when value is NOT IN another query' do
379
- # Boats that User 1 Cannot see
380
- acl = DataMapper::Query.new(repository(ADAPTER), QuerySpec::Permission, :user_id => 1, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
381
- query = { :port => 'Cape Town', :id.not => acl, :captain.like => 'J%' }
382
- boats = repository(ADAPTER) { QuerySpec::SailBoat.all(query) }
383
- boats.should have(1).entries
384
- boats.entries[0].id.should == 3
385
- end
386
- end # describe sub-selecting
387
-
388
- describe 'when linking associated objects' do
389
- before(:each) do
390
- [ QuerySpec::Region, QuerySpec::Factory, QuerySpec::Vehicle ].each { |m| m.auto_migrate! }
391
-
392
- QuerySpec::Region.create(:id => 1, :name => 'North West', :type => 'commercial')
393
- QuerySpec::Factory.create(:id => 2000, :region_id => 1, :name => 'North West Plant')
394
- QuerySpec::Vehicle.create(:id => 1, :factory_id => 2000, :name => '10 ton delivery truck')
395
-
396
- Namespace::Region.auto_migrate!
397
- Namespace::Factory.auto_migrate!
398
- Namespace::Vehicle.auto_migrate!
399
-
400
- Namespace::Region.create(:id => 1, :name => 'North West')
401
- Namespace::Factory.create(:id => 2000, :region_id => 1, :name => 'North West Plant')
402
- Namespace::Vehicle.create(:id => 1, :factory_id => 2000, :name => '10 ton delivery truck')
403
- end
404
-
405
- it 'should require that all properties in :fields and all :links come from the same repository' #do
406
- # land = QuerySpec::Factory.properties(:mock)[:land]
407
- # fields = []
408
- # QuerySpec::Vehicle.properties(ADAPTER).map do |property|
409
- # fields << property
410
- # end
411
- # fields << land
412
- #
413
- # lambda{
414
- # begin
415
- # results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ :factory ], :fields => fields) }
416
- # rescue RuntimeError
417
- # $!.message.should == "Property QuerySpec::Factory.land not available in repository #{ADAPTER}"
418
- # raise $!
419
- # end
420
- # }.should raise_error(RuntimeError)
421
- #end
422
-
423
- it 'should accept a DM::Assoc::Relationship as a link' do
424
- factory = DataMapper::Associations::Relationship.new(
425
- :factory,
426
- ADAPTER,
427
- QuerySpec::Vehicle,
428
- QuerySpec::Factory,
429
- { :child_key => [ :factory_id ], :parent_key => [ :id ] }
430
- )
431
- results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ factory ]) }
432
- results.should have(1).entries
433
- end
434
-
435
- it 'should accept a symbol of an association name as a link' do
436
- results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ :factory ]) }
437
- results.should have(1).entries
438
- end
439
-
440
- it 'should accept a string of an association name as a link' do
441
- results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ 'factory' ]) }
442
- results.should have(1).entries
443
- end
444
-
445
- it 'should accept a mixture of items as a set of links' do
446
- region = DataMapper::Associations::Relationship.new(
447
- :region,
448
- ADAPTER,
449
- QuerySpec::Factory,
450
- QuerySpec::Region,
451
- { :child_key => [ :region_id ], :parent_key => [ :id ] }
452
- )
453
- results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ 'factory', region ]) }
454
- results.should have(1).entries
455
- end
456
-
457
- it 'should only accept a DM::Assoc::Relationship, String & Symbol as a link' do
458
- lambda{
459
- DataMapper::Query.new(repository(ADAPTER), QuerySpec::Vehicle, :links => [1])
460
- }.should raise_error(ArgumentError)
461
- end
462
-
463
- it 'should have a association by the name of the Symbol or String' do
464
- lambda{
465
- DataMapper::Query.new(repository(ADAPTER), QuerySpec::Vehicle, :links => [ 'Sailing' ])
466
- }.should raise_error(ArgumentError)
467
-
468
- lambda{
469
- DataMapper::Query.new(repository(ADAPTER), QuerySpec::Vehicle, :links => [ :sailing ])
470
- }.should raise_error(ArgumentError)
471
- end
472
-
473
- it 'should create an n-level query path' do
474
- QuerySpec::Vehicle.factory.region.model.should == QuerySpec::Region
475
- QuerySpec::Vehicle.factory.region.name.property.should == QuerySpec::Region.properties(QuerySpec::Region.repository.name)[ :name ]
476
- end
477
-
478
- it 'should accept a DM::QueryPath as the key to a condition' do
479
- vehicle = QuerySpec::Vehicle.first(QuerySpec::Vehicle.factory.region.name => 'North West')
480
- vehicle.name.should == '10 ton delivery truck'
481
-
482
- vehicle = Namespace::Vehicle.first(Namespace::Vehicle.factory.region.name => 'North West')
483
- vehicle.name.should == '10 ton delivery truck'
484
- end
485
-
486
- it "should accept a string representing a DM::QueryPath as they key to a condition" do
487
- vehicle = QuerySpec::Vehicle.first("factory.region.name" => 'North West')
488
- vehicle.name.should == '10 ton delivery truck'
489
- end
490
-
491
- it "should accept 'id' and 'type' as endpoints on ah DM::QueryPath" do
492
- vehicle = QuerySpec::Vehicle.first( QuerySpec::Vehicle.factory.region.type => 'commercial' )
493
- vehicle.name.should == '10 ton delivery truck'
494
- vehicle = QuerySpec::Vehicle.first( QuerySpec::Vehicle.factory.region.id => 1 )
495
- vehicle.name.should == '10 ton delivery truck'
496
- end
497
-
498
- it 'should auto generate the link if a DM::Property from a different resource is in the :fields option'
499
-
500
- it 'should create links with composite keys'
501
-
502
- it 'should eager load associations' do
503
- repository(ADAPTER) do
504
- vehicle = QuerySpec::Vehicle.first(:includes => [ QuerySpec::Vehicle.factory ])
505
- end
506
- end
507
-
508
- it "should behave when using mocks" do
509
- QuerySpec::Group.should_receive(:all).with(:order => [ :id.asc ])
510
- QuerySpec::Group.all(:order => [ :id.asc ])
511
- end
512
- end # describe links
513
- end # DM::Query
514
- end
@@ -1,61 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
-
3
- if ADAPTER
4
- describe DataMapper::Repository, "with #{ADAPTER}" do
5
- before :all do
6
- class ::SerialFinderSpec
7
- include DataMapper::Resource
8
-
9
- property :id, Serial
10
- property :sample, String
11
-
12
- auto_migrate!(ADAPTER)
13
- end
14
-
15
- repository(ADAPTER).create((0...100).map { SerialFinderSpec.new(:sample => rand.to_s) })
16
- end
17
-
18
- before do
19
- @repository = repository(ADAPTER)
20
- @model = SerialFinderSpec
21
- @query = DataMapper::Query.new(@repository, @model)
22
- end
23
-
24
- it 'should be serializable with Marshal' do
25
- Marshal.load(Marshal.dump(@repository)).should == @repository
26
- end
27
-
28
- it "should throw an exception if the named repository is unknown" do
29
- r = DataMapper::Repository.new(:completely_bogus)
30
- lambda { r.adapter }.should raise_error(ArgumentError)
31
- end
32
-
33
- it "should return all available rows" do
34
- @repository.read_many(@query).should have(100).entries
35
- end
36
-
37
- it "should allow limit and offset" do
38
- @repository.read_many(@query.merge(:limit => 50)).should have(50).entries
39
-
40
- collection = @repository.read_many(@query.merge(:limit => 20, :offset => 40))
41
- collection.should have(20).entries
42
- collection.map { |entry| entry.id }.should == @repository.read_many(@query)[40...60].map { |entry| entry.id }
43
- end
44
-
45
- it "should lazy-load missing attributes" do
46
- sfs = @repository.read_one(@query.merge(:fields => [ :id ], :limit => 1))
47
- sfs.should be_a_kind_of(@model)
48
- sfs.should_not be_a_new_record
49
-
50
- sfs.attribute_loaded?(:sample).should be_false
51
- sfs.sample.should_not be_nil
52
- end
53
-
54
- it "should translate an Array to an IN clause" do
55
- ids = @repository.read_many(@query.merge(:fields => [ :id ], :limit => 10)).map { |entry| entry.id }
56
- results = @repository.read_many(@query.merge(:id => ids))
57
-
58
- results.map { |entry| entry.id }.should == ids
59
- end
60
- end
61
- end