public
Rubygem
Description: DataMapper - Core
Homepage: http://datamapper.org
Clone URL: git://github.com/sam/dm-core.git
Search Repo:
Collection#unique is now supported through group by
dbussink (author)
Sun Jul 13 10:57:25 -0700 2008
commit  a80911803c9d74615b6aedf444fbb99758ce5ddb
tree    dca1e2f379461a92b4b4cecd4733c245aefebb62
parent  8d917f972d2a6524df52de65b3e98308a1398df7
...
228
229
230
 
231
232
233
...
317
318
319
 
 
 
 
 
 
 
 
 
 
 
 
320
321
322
...
228
229
230
231
232
233
234
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
0
@@ -228,6 +228,7 @@ module DataMapper
0
           statement << " FROM #{quote_table_name(query.model.storage_name(query.repository.name))}"
0
           statement << links_statement(query) if query.links.any?
0
           statement << " WHERE #{conditions_statement(query)}" if query.conditions.any?
0
+ statement << " GROUP BY #{group_by_statement(query)}" if query.unique?
0
           statement << " ORDER BY #{order_statement(query)}" if query.order.any?
0
           statement << " LIMIT #{quote_column_value(query.limit)}" if query.limit
0
           statement << " OFFSET #{quote_column_value(query.offset)}" if query.offset && query.offset > 0
0
@@ -317,6 +318,18 @@ module DataMapper
0
           end * ', '
0
         end
0
 
0
+ def group_by_statement(query)
0
+ if query.unique?
0
+ query.fields.map do |field|
0
+ property_to_column_name(query.repository, field, true)
0
+ end.join(", ")
0
+ elsif query.group_by
0
+ query.group_by.map do |field|
0
+ property_to_column_name(query.repository, field, true)
0
+ end.join(", ")
0
+ end
0
+ end
0
+
0
         def condition_statement(query, operator, left_condition, right_condition)
0
           return left_condition if operator == :raw
0
 
...
19
20
21
22
 
 
23
24
25
26
27
 
28
29
30
...
19
20
21
 
22
23
24
25
26
27
 
28
29
30
31
0
@@ -19,12 +19,13 @@ module DataMapper
0
       def get_children(parent, options = {}, finder = :all, *args)
0
         query = @query.merge(options).merge(child_key.to_query(parent_key.get(parent)))
0
 
0
- query[:links] = links
0
+ query[:links] = links
0
+ query[:unique] = true
0
 
0
         with_repository(parent) do
0
           results = grandchild_model.send(finder, *(args << query))
0
           # FIXME: remove the need for the uniq.freeze
0
- finder == :all ? (@mutable ? results.uniq : results.uniq.freeze) : results
0
+ finder == :all ? (@mutable ? results : results.freeze) : results
0
         end
0
       end
0
 
...
3
4
5
6
 
7
8
9
 
10
11
12
...
14
15
16
 
 
 
 
17
18
19
...
42
43
44
 
45
46
47
...
67
68
69
 
70
71
72
...
136
137
138
 
139
140
141
...
157
158
159
 
160
161
162
...
164
165
166
 
167
168
169
...
223
224
225
226
227
228
 
 
 
 
 
229
230
231
...
3
4
5
 
6
7
8
 
9
10
11
12
...
14
15
16
17
18
19
20
21
22
23
...
46
47
48
49
50
51
52
...
72
73
74
75
76
77
78
...
142
143
144
145
146
147
148
...
164
165
166
167
168
169
170
...
172
173
174
175
176
177
178
...
232
233
234
 
 
 
235
236
237
238
239
240
241
242
0
@@ -3,10 +3,10 @@ module DataMapper
0
     include Assertions
0
 
0
     OPTIONS = [
0
- :reload, :offset, :limit, :order, :add_reversed, :fields, :links, :includes, :conditions
0
+ :reload, :offset, :limit, :order, :add_reversed, :fields, :links, :includes, :conditions, :unique, :group_by
0
     ]
0
 
0
- attr_reader :repository, :model, *OPTIONS - [ :reload ]
0
+ attr_reader :repository, :model, *OPTIONS - [ :reload, :unique ]
0
     attr_writer :add_reversed
0
     alias add_reversed? add_reversed
0
 
0
@@ -14,6 +14,10 @@ module DataMapper
0
       @reload
0
     end
0
 
0
+ def unique?
0
+ @unique
0
+ end
0
+
0
     def reverse
0
       dup.reverse!
0
     end
0
@@ -42,6 +46,7 @@ module DataMapper
0
 
0
       # only overwrite the attributes with non-default values
0
       @reload = other.reload? unless other.reload? == false
0
+ @unique = other.unique? unless other.unique? == false
0
       @offset = other.offset unless other.offset == 0
0
       @limit = other.limit unless other.limit == nil
0
       @order = other.order unless other.order == model.default_order
0
@@ -67,6 +72,7 @@ module DataMapper
0
       # return hash == other.hash
0
       @model == other.model &&
0
       @reload == other.reload? &&
0
+ @unique == other.unique? &&
0
       @offset == other.offset &&
0
       @limit == other.limit &&
0
       @order == other.order && # order is significant, so do not sort this
0
@@ -136,6 +142,7 @@ module DataMapper
0
         [ :limit, limit ],
0
         [ :offset, offset ],
0
         [ :reload, reload? ],
0
+ [ :unique, unique? ],
0
       ]
0
 
0
       "#<#{self.class.name} #{attrs.map { |(k,v)| "@#{k}=#{v.inspect}" } * ' '}>"
0
@@ -157,6 +164,7 @@ module DataMapper
0
 
0
       @model = model # must be Class that includes DM::Resource
0
       @reload = options.fetch :reload, false # must be true or false
0
+ @unique = options.fetch :unique, false # must be true or false
0
       @offset = options.fetch :offset, 0 # must be an Integer greater than or equal to 0
0
       @limit = options.fetch :limit, nil # must be an Integer greater than or equal to 1
0
       @order = options.fetch :order, model.default_order # must be an Array of Symbol, DM::Query::Direction or DM::Property
0
@@ -164,6 +172,7 @@ module DataMapper
0
       @fields = options.fetch :fields, @properties.defaults # must be an Array of Symbol, String or DM::Property
0
       @links = options.fetch :links, [] # must be an Array of Tuples - Tuple [DM::Query,DM::Assoc::Relationship]
0
       @includes = options.fetch :includes, [] # must be an Array of DM::Query::Path
0
+ @group_by = options.fetch :group_by, nil # must be a an Array of Symbol, String or DM::Property
0
       @conditions = [] # must be an Array of triplets (or pairs when passing in raw String queries)
0
 
0
       # normalize order and fields
0
@@ -223,9 +232,11 @@ module DataMapper
0
 
0
     # validate the options
0
     def assert_valid_options(options)
0
- # validate the reload option
0
- if options.has_key?(:reload) && options[:reload] != true && options[:reload] != false
0
- raise ArgumentError, "+options[:reload]+ must be true or false, but was #{options[:reload].inspect}", caller(2)
0
+ # validate the reload option & unique option
0
+ ([ :reload, :unique ] & options.keys).each do |attribute|
0
+ if options[attribute] != true && options[attribute] != false
0
+ raise ArgumentError, "+options[:#{attribute}]+ must be true or false, but was #{options[attribute].inspect}", caller(2)
0
+ end
0
       end
0
 
0
       # validate the offset and limit options
...
136
137
138
139
140
141
142
...
136
137
138
 
139
140
141
0
@@ -136,7 +136,6 @@ if ADAPTER
0
     end
0
 
0
     it 'should handle get()' do
0
- pending "Collection#uniq isn't implemented, see lib/dm-core/associations/relationship_chain.rb:27"
0
       post = Post.get!(2)
0
       related_posts = Post.first.related_posts
0
       related_posts.get(2).should == post

Comments

    No one has commented yet.