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.
- data/.autotest +17 -14
- data/.gitignore +3 -1
- data/FAQ +6 -5
- data/History.txt +5 -39
- data/Manifest.txt +67 -76
- data/QUICKLINKS +1 -1
- data/README.txt +21 -15
- data/Rakefile +16 -15
- data/SPECS +2 -29
- data/TODO +1 -1
- data/dm-core.gemspec +11 -15
- data/lib/dm-core/adapters/abstract_adapter.rb +182 -185
- data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
- data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
- data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
- data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
- data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
- data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
- data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
- data/lib/dm-core/adapters.rb +135 -16
- data/lib/dm-core/associations/many_to_many.rb +372 -90
- data/lib/dm-core/associations/many_to_one.rb +220 -73
- data/lib/dm-core/associations/one_to_many.rb +319 -255
- data/lib/dm-core/associations/one_to_one.rb +66 -53
- data/lib/dm-core/associations/relationship.rb +560 -158
- data/lib/dm-core/collection.rb +1104 -381
- data/lib/dm-core/core_ext/kernel.rb +12 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +4 -34
- data/lib/dm-core/migrations.rb +1283 -0
- data/lib/dm-core/model/descendant_set.rb +81 -0
- data/lib/dm-core/model/hook.rb +45 -0
- data/lib/dm-core/model/is.rb +32 -0
- data/lib/dm-core/model/property.rb +248 -0
- data/lib/dm-core/model/relationship.rb +335 -0
- data/lib/dm-core/model/scope.rb +90 -0
- data/lib/dm-core/model.rb +570 -369
- data/lib/dm-core/property.rb +753 -280
- data/lib/dm-core/property_set.rb +141 -98
- data/lib/dm-core/query/conditions/comparison.rb +814 -0
- data/lib/dm-core/query/conditions/operation.rb +247 -0
- data/lib/dm-core/query/direction.rb +43 -0
- data/lib/dm-core/query/operator.rb +42 -0
- data/lib/dm-core/query/path.rb +102 -0
- data/lib/dm-core/query/sort.rb +45 -0
- data/lib/dm-core/query.rb +974 -492
- data/lib/dm-core/repository.rb +147 -107
- data/lib/dm-core/resource.rb +644 -429
- data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
- data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
- data/lib/dm-core/support/chainable.rb +20 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/equalizer.rb +23 -0
- data/lib/dm-core/support/logger.rb +13 -0
- data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
- data/lib/dm-core/transaction.rb +333 -92
- data/lib/dm-core/type.rb +98 -60
- data/lib/dm-core/types/boolean.rb +1 -1
- data/lib/dm-core/types/discriminator.rb +34 -20
- data/lib/dm-core/types/object.rb +7 -4
- data/lib/dm-core/types/paranoid_boolean.rb +11 -9
- data/lib/dm-core/types/paranoid_datetime.rb +11 -9
- data/lib/dm-core/types/serial.rb +3 -3
- data/lib/dm-core/types/text.rb +3 -4
- data/lib/dm-core/version.rb +1 -1
- data/lib/dm-core.rb +106 -110
- data/script/performance.rb +102 -109
- data/script/profile.rb +169 -38
- data/spec/lib/adapter_helpers.rb +105 -0
- data/spec/lib/collection_helpers.rb +18 -0
- data/spec/lib/counter_adapter.rb +34 -0
- data/spec/lib/pending_helpers.rb +27 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
- data/spec/public/associations/many_to_many_spec.rb +193 -0
- data/spec/public/associations/many_to_one_spec.rb +73 -0
- data/spec/public/associations/one_to_many_spec.rb +77 -0
- data/spec/public/associations/one_to_one_spec.rb +156 -0
- data/spec/public/collection_spec.rb +65 -0
- data/spec/public/model/relationship_spec.rb +924 -0
- data/spec/public/model_spec.rb +159 -0
- data/spec/public/property_spec.rb +829 -0
- data/spec/public/resource_spec.rb +71 -0
- data/spec/public/sel_spec.rb +44 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +317 -0
- data/spec/public/shared/collection_shared_spec.rb +1723 -0
- data/spec/public/shared/finder_shared_spec.rb +1619 -0
- data/spec/public/shared/resource_shared_spec.rb +924 -0
- data/spec/public/shared/sel_shared_spec.rb +112 -0
- data/spec/public/transaction_spec.rb +129 -0
- data/spec/public/types/discriminator_spec.rb +130 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
- data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
- data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +194 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +142 -0
- data/spec/semipublic/property_spec.rb +61 -0
- data/spec/semipublic/query/conditions_spec.rb +528 -0
- data/spec/semipublic/query/path_spec.rb +443 -0
- data/spec/semipublic/query_spec.rb +2626 -0
- data/spec/semipublic/resource_spec.rb +47 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
- data/spec/spec.opts +3 -1
- data/spec/spec_helper.rb +80 -57
- data/tasks/ci.rb +19 -31
- data/tasks/dm.rb +43 -48
- data/tasks/doc.rb +8 -11
- data/tasks/gemspec.rb +5 -5
- data/tasks/hoe.rb +15 -16
- data/tasks/install.rb +8 -10
- metadata +72 -93
- data/lib/dm-core/associations/relationship_chain.rb +0 -81
- data/lib/dm-core/associations.rb +0 -207
- data/lib/dm-core/auto_migrations.rb +0 -105
- data/lib/dm-core/dependency_queue.rb +0 -32
- data/lib/dm-core/hook.rb +0 -11
- data/lib/dm-core/is.rb +0 -16
- data/lib/dm-core/logger.rb +0 -232
- data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
- data/lib/dm-core/migrator.rb +0 -29
- data/lib/dm-core/scope.rb +0 -58
- data/lib/dm-core/support/array.rb +0 -13
- data/lib/dm-core/support/assertions.rb +0 -8
- data/lib/dm-core/support/errors.rb +0 -23
- data/lib/dm-core/support/kernel.rb +0 -11
- data/lib/dm-core/support/symbol.rb +0 -41
- data/lib/dm-core/support.rb +0 -7
- data/lib/dm-core/type_map.rb +0 -80
- data/lib/dm-core/types.rb +0 -19
- data/script/all +0 -4
- data/spec/integration/association_spec.rb +0 -1382
- data/spec/integration/association_through_spec.rb +0 -203
- data/spec/integration/associations/many_to_many_spec.rb +0 -449
- data/spec/integration/associations/many_to_one_spec.rb +0 -163
- data/spec/integration/associations/one_to_many_spec.rb +0 -188
- data/spec/integration/auto_migrations_spec.rb +0 -413
- data/spec/integration/collection_spec.rb +0 -1073
- data/spec/integration/data_objects_adapter_spec.rb +0 -32
- data/spec/integration/dependency_queue_spec.rb +0 -46
- data/spec/integration/model_spec.rb +0 -197
- data/spec/integration/mysql_adapter_spec.rb +0 -85
- data/spec/integration/postgres_adapter_spec.rb +0 -731
- data/spec/integration/property_spec.rb +0 -253
- data/spec/integration/query_spec.rb +0 -514
- data/spec/integration/repository_spec.rb +0 -61
- data/spec/integration/resource_spec.rb +0 -513
- data/spec/integration/sqlite3_adapter_spec.rb +0 -352
- data/spec/integration/sti_spec.rb +0 -273
- data/spec/integration/strategic_eager_loading_spec.rb +0 -156
- data/spec/integration/transaction_spec.rb +0 -75
- data/spec/integration/type_spec.rb +0 -275
- data/spec/lib/logging_helper.rb +0 -18
- data/spec/lib/mock_adapter.rb +0 -27
- data/spec/lib/model_loader.rb +0 -100
- data/spec/lib/publicize_methods.rb +0 -28
- data/spec/models/content.rb +0 -16
- data/spec/models/vehicles.rb +0 -34
- data/spec/models/zoo.rb +0 -48
- data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
- data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
- data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
- data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
- data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
- data/spec/unit/associations/many_to_many_spec.rb +0 -32
- data/spec/unit/associations/many_to_one_spec.rb +0 -159
- data/spec/unit/associations/one_to_many_spec.rb +0 -393
- data/spec/unit/associations/one_to_one_spec.rb +0 -7
- data/spec/unit/associations/relationship_spec.rb +0 -71
- data/spec/unit/associations_spec.rb +0 -242
- data/spec/unit/auto_migrations_spec.rb +0 -111
- data/spec/unit/collection_spec.rb +0 -182
- data/spec/unit/data_mapper_spec.rb +0 -35
- data/spec/unit/identity_map_spec.rb +0 -126
- data/spec/unit/is_spec.rb +0 -80
- data/spec/unit/migrator_spec.rb +0 -33
- data/spec/unit/model_spec.rb +0 -321
- data/spec/unit/naming_conventions_spec.rb +0 -36
- data/spec/unit/property_set_spec.rb +0 -90
- data/spec/unit/property_spec.rb +0 -753
- data/spec/unit/query_spec.rb +0 -571
- data/spec/unit/repository_spec.rb +0 -93
- data/spec/unit/resource_spec.rb +0 -649
- data/spec/unit/scope_spec.rb +0 -142
- data/spec/unit/transaction_spec.rb +0 -493
- data/spec/unit/type_map_spec.rb +0 -114
- 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
|