dm-aggregates 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.
@@ -1,3 +1,7 @@
1
+ === 0.10.0 / 2009-10-15
2
+
3
+ * Updated to work with dm-core 0.10.0
4
+
1
5
  === 0.9.11 / 2009-03-29
2
6
 
3
7
  * No changes this version
data/Manifest.txt CHANGED
@@ -1,16 +1,17 @@
1
- History.txt
1
+ History.rdoc
2
2
  LICENSE
3
3
  Manifest.txt
4
- README.txt
4
+ README.rdoc
5
5
  Rakefile
6
6
  TODO
7
7
  lib/dm-aggregates.rb
8
8
  lib/dm-aggregates/adapters/data_objects_adapter.rb
9
9
  lib/dm-aggregates/aggregate_functions.rb
10
10
  lib/dm-aggregates/collection.rb
11
+ lib/dm-aggregates/core_ext/symbol.rb
11
12
  lib/dm-aggregates/model.rb
13
+ lib/dm-aggregates/query.rb
12
14
  lib/dm-aggregates/repository.rb
13
- lib/dm-aggregates/support/symbol.rb
14
15
  lib/dm-aggregates/version.rb
15
16
  spec/public/collection_spec.rb
16
17
  spec/public/model_spec.rb
File without changes
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'pathname'
2
- require 'rubygems'
3
2
 
4
3
  ROOT = Pathname(__FILE__).dirname.expand_path
5
4
  JRUBY = RUBY_PLATFORM =~ /java/
@@ -14,10 +13,10 @@ GEM_NAME = 'dm-aggregates'
14
13
  GEM_VERSION = DataMapper::Aggregates::VERSION
15
14
  GEM_DEPENDENCIES = [['dm-core', GEM_VERSION]]
16
15
  GEM_CLEAN = %w[ log pkg coverage ]
17
- GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO History.txt ] }
16
+ GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.rdoc LICENSE TODO History.rdoc ] }
18
17
 
19
18
  PROJECT_NAME = 'datamapper'
20
- PROJECT_URL = "http://github.com/sam/dm-more/tree/master/#{GEM_NAME}"
19
+ PROJECT_URL = "http://github.com/datamapper/dm-more/tree/master/#{GEM_NAME}"
21
20
  PROJECT_DESCRIPTION = PROJECT_SUMMARY = 'DataMapper plugin providing support for aggregates, functions on collections and datasets'
22
21
 
23
22
  [ ROOT, ROOT.parent ].each do |dir|
@@ -1,24 +1,44 @@
1
1
  module DataMapper
2
- module Adapters
3
- class DataObjectsAdapter
2
+ module Aggregates
3
+ module DataObjectsAdapter
4
+ def self.included(base)
5
+ base.send(:include, SQL)
6
+ end
7
+
4
8
  def aggregate(query)
5
- with_reader(read_statement(query), query.bind_values) do |reader|
6
- results = []
7
-
8
- while(reader.next!) do
9
- row = query.fields.zip(reader.values).map do |field,value|
10
- if field.respond_to?(:operator)
11
- send(field.operator, field.target, value)
12
- else
13
- field.typecast(value)
9
+ fields = query.fields
10
+ types = fields.map { |p| p.respond_to?(:operator) ? String : p.primitive }
11
+
12
+ field_size = fields.size
13
+
14
+ records = []
15
+
16
+ with_connection do |connection|
17
+ statement, bind_values = select_statement(query)
18
+
19
+ command = connection.create_command(statement)
20
+ command.set_types(types)
21
+
22
+ reader = command.execute_reader(*bind_values)
23
+
24
+ begin
25
+ while(reader.next!)
26
+ row = fields.zip(reader.values).map do |field, value|
27
+ if field.respond_to?(:operator)
28
+ send(field.operator, field.target, value)
29
+ else
30
+ field.typecast(value)
31
+ end
14
32
  end
15
- end
16
33
 
17
- results << (query.fields.size > 1 ? row : row[0])
34
+ records << (field_size > 1 ? row : row[0])
35
+ end
36
+ ensure
37
+ reader.close
18
38
  end
19
-
20
- results
21
39
  end
40
+
41
+ records
22
42
  end
23
43
 
24
44
  private
@@ -44,26 +64,32 @@ module DataMapper
44
64
  end
45
65
 
46
66
  module SQL
47
- private
48
-
49
- alias original_property_to_column_name property_to_column_name
67
+ def self.included(base)
68
+ base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
69
+ # FIXME: figure out a cleaner approach than AMC
70
+ alias property_to_column_name_without_operator property_to_column_name
71
+ alias property_to_column_name property_to_column_name_with_operator
72
+ RUBY
73
+ end
50
74
 
51
- def property_to_column_name(repository, property, qualify)
75
+ def property_to_column_name_with_operator(property, qualify)
52
76
  case property
53
- when Query::Operator
54
- aggregate_field_statement(repository, property.operator, property.target, qualify)
55
- when Property, Query::Path
56
- original_property_to_column_name(repository, property, qualify)
77
+ when DataMapper::Query::Operator
78
+ aggregate_field_statement(property.operator, property.target, qualify)
79
+
80
+ when Property, DataMapper::Query::Path
81
+ property_to_column_name_without_operator(property, qualify)
82
+
57
83
  else
58
84
  raise ArgumentError, "+property+ must be a DataMapper::Query::Operator, a DataMapper::Property or a Query::Path, but was a #{property.class} (#{property.inspect})"
59
85
  end
60
86
  end
61
87
 
62
- def aggregate_field_statement(repository, aggregate_function, property, qualify)
88
+ def aggregate_field_statement(aggregate_function, property, qualify)
63
89
  column_name = if aggregate_function == :count && property == :all
64
90
  '*'
65
91
  else
66
- property_to_column_name(repository, property, qualify)
92
+ property_to_column_name(property, qualify)
67
93
  end
68
94
 
69
95
  function_name = case aggregate_function
@@ -78,8 +104,22 @@ module DataMapper
78
104
  "#{function_name}(#{column_name})"
79
105
  end
80
106
  end # module SQL
81
-
82
- include SQL
83
107
  end # class DataObjectsAdapter
108
+ end # module Aggregates
109
+
110
+ module Adapters
111
+ extendable do
112
+
113
+ # TODO: document
114
+ # @api private
115
+ def const_added(const_name)
116
+ if DataMapper::Aggregates.const_defined?(const_name)
117
+ adapter = const_get(const_name)
118
+ adapter.send(:include, DataMapper::Aggregates.const_get(const_name))
119
+ end
120
+
121
+ super
122
+ end
123
+ end
84
124
  end # module Adapters
85
125
  end # module DataMapper
@@ -1,200 +1,203 @@
1
1
  module DataMapper
2
- module AggregateFunctions
3
- # Count results (given the conditions)
4
- #
5
- # @example the count of all friends
6
- # Friend.count
7
- #
8
- # @example the count of all friends older then 18
9
- # Friend.count(:age.gt => 18)
10
- #
11
- # @example the count of all your female friends
12
- # Friend.count(:conditions => [ 'gender = ?', 'female' ])
13
- #
14
- # @example the count of all friends with an address (NULL values are not included)
15
- # Friend.count(:address)
16
- #
17
- # @example the count of all friends with an address that are older then 18
18
- # Friend.count(:address, :age.gt => 18)
19
- #
20
- # @example the count of all your female friends with an address
21
- # Friend.count(:address, :conditions => [ 'gender = ?', 'female' ])
22
- #
23
- # @param property [Symbol] of the property you with to count (optional)
24
- # @param opts [Hash, Symbol] the conditions
25
- #
26
- # @return [Integer] return the count given the conditions
27
- #
28
- # @api public
29
- def count(*args)
30
- query = args.last.kind_of?(Hash) ? args.pop : {}
31
- property_name = args.first
32
-
33
- if property_name
34
- assert_kind_of 'property', property_by_name(property_name), Property
2
+ module Aggregates
3
+ module Functions
4
+ # Count results (given the conditions)
5
+ #
6
+ # @example the count of all friends
7
+ # Friend.count
8
+ #
9
+ # @example the count of all friends older then 18
10
+ # Friend.count(:age.gt => 18)
11
+ #
12
+ # @example the count of all your female friends
13
+ # Friend.count(:conditions => [ 'gender = ?', 'female' ])
14
+ #
15
+ # @example the count of all friends with an address (NULL values are not included)
16
+ # Friend.count(:address)
17
+ #
18
+ # @example the count of all friends with an address that are older then 18
19
+ # Friend.count(:address, :age.gt => 18)
20
+ #
21
+ # @example the count of all your female friends with an address
22
+ # Friend.count(:address, :conditions => [ 'gender = ?', 'female' ])
23
+ #
24
+ # @param property [Symbol] of the property you with to count (optional)
25
+ # @param opts [Hash, Symbol] the conditions
26
+ #
27
+ # @return [Integer] return the count given the conditions
28
+ #
29
+ # @api public
30
+ def count(*args)
31
+ query = args.last.kind_of?(Hash) ? args.pop : {}
32
+ property_name = args.first
33
+
34
+ if property_name
35
+ assert_kind_of 'property', property_by_name(property_name), Property
36
+ end
37
+
38
+ aggregate(query.merge(:fields => [ property_name ? property_name.count : :all.count ]))
35
39
  end
36
40
 
37
- aggregate(query.merge(:fields => [ property_name ? property_name.count : :all.count ]))
38
- end
39
-
40
- # Get the lowest value of a property
41
- #
42
- # @example the age of the youngest friend
43
- # Friend.min(:age)
44
- #
45
- # @example the age of the youngest female friend
46
- # Friend.min(:age, :conditions => [ 'gender = ?', 'female' ])
47
- #
48
- # @param property [Symbol] the property you wish to get the lowest value of
49
- # @param opts [Hash, Symbol] the conditions
50
- #
51
- # @return [Integer] return the lowest value of a property given the conditions
52
- #
53
- # @api public
54
- def min(*args)
55
- query = args.last.kind_of?(Hash) ? args.pop : {}
56
- property_name = args.first
57
-
58
- assert_property_type property_name, Integer, Float, BigDecimal, DateTime, Date, Time
59
-
60
- aggregate(query.merge(:fields => [ property_name.min ]))
61
- end
41
+ # Get the lowest value of a property
42
+ #
43
+ # @example the age of the youngest friend
44
+ # Friend.min(:age)
45
+ #
46
+ # @example the age of the youngest female friend
47
+ # Friend.min(:age, :conditions => [ 'gender = ?', 'female' ])
48
+ #
49
+ # @param property [Symbol] the property you wish to get the lowest value of
50
+ # @param opts [Hash, Symbol] the conditions
51
+ #
52
+ # @return [Integer] return the lowest value of a property given the conditions
53
+ #
54
+ # @api public
55
+ def min(*args)
56
+ query = args.last.kind_of?(Hash) ? args.pop : {}
57
+ property_name = args.first
58
+
59
+ assert_property_type property_name, Integer, Float, BigDecimal, DateTime, Date, Time
60
+
61
+ aggregate(query.merge(:fields => [ property_name.min ]))
62
+ end
62
63
 
63
- # Get the highest value of a property
64
- #
65
- # @example the age of the oldest friend
66
- # Friend.max(:age)
67
- #
68
- # @example the age of the oldest female friend
69
- # Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])
70
- #
71
- # @param property [Symbol] the property you wish to get the highest value of
72
- # @param opts [Hash, Symbol] the conditions
73
- #
74
- # @return [Integer] return the highest value of a property given the conditions
75
- #
76
- # @api public
77
- def max(*args)
78
- query = args.last.kind_of?(Hash) ? args.pop : {}
79
- property_name = args.first
80
-
81
- assert_property_type property_name, Integer, Float, BigDecimal, DateTime, Date, Time
82
-
83
- aggregate(query.merge(:fields => [ property_name.max ]))
84
- end
64
+ # Get the highest value of a property
65
+ #
66
+ # @example the age of the oldest friend
67
+ # Friend.max(:age)
68
+ #
69
+ # @example the age of the oldest female friend
70
+ # Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])
71
+ #
72
+ # @param property [Symbol] the property you wish to get the highest value of
73
+ # @param opts [Hash, Symbol] the conditions
74
+ #
75
+ # @return [Integer] return the highest value of a property given the conditions
76
+ #
77
+ # @api public
78
+ def max(*args)
79
+ query = args.last.kind_of?(Hash) ? args.pop : {}
80
+ property_name = args.first
81
+
82
+ assert_property_type property_name, Integer, Float, BigDecimal, DateTime, Date, Time
83
+
84
+ aggregate(query.merge(:fields => [ property_name.max ]))
85
+ end
85
86
 
86
- # Get the average value of a property
87
- #
88
- # @example the average age of all friends
89
- # Friend.avg(:age)
90
- #
91
- # @example the average age of all female friends
92
- # Friend.avg(:age, :conditions => [ 'gender = ?', 'female' ])
93
- #
94
- # @param property [Symbol] the property you wish to get the average value of
95
- # @param opts [Hash, Symbol] the conditions
96
- #
97
- # @return [Integer] return the average value of a property given the conditions
98
- #
99
- # @api public
100
- def avg(*args)
101
- query = args.last.kind_of?(Hash) ? args.pop : {}
102
- property_name = args.first
103
-
104
- assert_property_type property_name, Integer, Float, BigDecimal
105
-
106
- aggregate(query.merge(:fields => [ property_name.avg ]))
107
- end
87
+ # Get the average value of a property
88
+ #
89
+ # @example the average age of all friends
90
+ # Friend.avg(:age)
91
+ #
92
+ # @example the average age of all female friends
93
+ # Friend.avg(:age, :conditions => [ 'gender = ?', 'female' ])
94
+ #
95
+ # @param property [Symbol] the property you wish to get the average value of
96
+ # @param opts [Hash, Symbol] the conditions
97
+ #
98
+ # @return [Integer] return the average value of a property given the conditions
99
+ #
100
+ # @api public
101
+ def avg(*args)
102
+ query = args.last.kind_of?(Hash) ? args.pop : {}
103
+ property_name = args.first
104
+
105
+ assert_property_type property_name, Integer, Float, BigDecimal
106
+
107
+ aggregate(query.merge(:fields => [ property_name.avg ]))
108
+ end
108
109
 
109
- # Get the total value of a property
110
- #
111
- # @example the total age of all friends
112
- # Friend.sum(:age)
113
- #
114
- # @example the total age of all female friends
115
- # Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])
116
- #
117
- # @param property [Symbol] the property you wish to get the total value of
118
- # @param opts [Hash, Symbol] the conditions
119
- #
120
- # @return [Integer] return the total value of a property given the conditions
121
- #
122
- # @api public
123
- def sum(*args)
124
- query = args.last.kind_of?(Hash) ? args.pop : {}
125
- property_name = args.first
126
-
127
- assert_property_type property_name, Integer, Float, BigDecimal
128
-
129
- aggregate(query.merge(:fields => [ property_name.sum ]))
130
- end
110
+ # Get the total value of a property
111
+ #
112
+ # @example the total age of all friends
113
+ # Friend.sum(:age)
114
+ #
115
+ # @example the total age of all female friends
116
+ # Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])
117
+ #
118
+ # @param property [Symbol] the property you wish to get the total value of
119
+ # @param opts [Hash, Symbol] the conditions
120
+ #
121
+ # @return [Integer] return the total value of a property given the conditions
122
+ #
123
+ # @api public
124
+ def sum(*args)
125
+ query = args.last.kind_of?(Hash) ? args.pop : {}
126
+ property_name = args.first
127
+
128
+ assert_property_type property_name, Integer, Float, BigDecimal
129
+
130
+ aggregate(query.merge(:fields => [ property_name.sum ]))
131
+ end
131
132
 
132
- # Perform aggregate queries
133
- #
134
- # @example the count of friends
135
- # Friend.aggregate(:all.count)
136
- #
137
- # @example the minimum age, the maximum age and the total age of friends
138
- # Friend.aggregate(:age.min, :age.max, :age.sum)
139
- #
140
- # @example the average age, grouped by gender
141
- # Friend.aggregate(:age.avg, :fields => [ :gender ])
142
- #
143
- # @param aggregates [Symbol, ...] operators to aggregate with
144
- # @params query [Hash] the conditions
145
- #
146
- # @return [Array,Numeric,DateTime,Date,Time] the results of the
147
- # aggregate query
148
- #
149
- # @api public
150
- def aggregate(*args)
151
- query = args.last.kind_of?(Hash) ? args.pop : {}
152
-
153
- query[:fields] ||= []
154
- query[:fields] |= args
155
- query[:fields].map! { |f| normalize_field(f) }
156
- query[:order] ||= query[:fields].select { |p| p.kind_of?(Property) }
157
-
158
- raise ArgumentError, 'query[:fields] must not be empty' if query[:fields].empty?
159
-
160
- query = scoped_query(query)
161
-
162
- if query.fields.any? { |p| p.kind_of?(Property) }
163
- # explicitly specify the fields to circumvent a bug in Query#update
164
- query.repository.aggregate(query.update(:fields => query.fields, :unique => true))
165
- else
166
- query.repository.aggregate(query).first # only return one row
133
+ # Perform aggregate queries
134
+ #
135
+ # @example the count of friends
136
+ # Friend.aggregate(:all.count)
137
+ #
138
+ # @example the minimum age, the maximum age and the total age of friends
139
+ # Friend.aggregate(:age.min, :age.max, :age.sum)
140
+ #
141
+ # @example the average age, grouped by gender
142
+ # Friend.aggregate(:age.avg, :fields => [ :gender ])
143
+ #
144
+ # @param aggregates [Symbol, ...] operators to aggregate with
145
+ # @params query [Hash] the conditions
146
+ #
147
+ # @return [Array,Numeric,DateTime,Date,Time] the results of the
148
+ # aggregate query
149
+ #
150
+ # @api public
151
+ def aggregate(*args)
152
+ query = args.last.kind_of?(Hash) ? args.pop : {}
153
+
154
+ query[:fields] ||= []
155
+ query[:fields] |= args
156
+ query[:fields].map! { |f| normalize_field(f) }
157
+ query[:order] ||= query[:fields].select { |p| p.kind_of?(Property) }
158
+
159
+ raise ArgumentError, 'query[:fields] must not be empty' if query[:fields].empty?
160
+
161
+ query = scoped_query(query)
162
+
163
+ if query.fields.any? { |p| p.kind_of?(Property) }
164
+ query.repository.aggregate(query.update(:unique => true))
165
+ else
166
+ query.repository.aggregate(query).first # only return one row
167
+ end
167
168
  end
168
- end
169
169
 
170
- private
170
+ private
171
171
 
172
- def assert_property_type(name, *types)
173
- if name.nil?
174
- raise ArgumentError, 'property name must not be nil'
175
- end
172
+ def assert_property_type(name, *types)
173
+ if name.nil?
174
+ raise ArgumentError, 'property name must not be nil'
175
+ end
176
176
 
177
- type = property_by_name(name).type
177
+ type = property_by_name(name).type
178
178
 
179
- unless types.include?(type)
180
- raise ArgumentError, "#{name} must be #{types * ' or '}, but was #{type}"
179
+ unless types.include?(type)
180
+ raise ArgumentError, "#{name} must be #{types * ' or '}, but was #{type}"
181
+ end
181
182
  end
182
- end
183
183
 
184
- def normalize_field(field)
185
- assert_kind_of 'field', field, Query::Operator, Symbol, Property
184
+ def normalize_field(field)
185
+ assert_kind_of 'field', field, DataMapper::Query::Operator, Symbol, Property
186
+
187
+ case field
188
+ when DataMapper::Query::Operator
189
+ if field.target == :all
190
+ field
191
+ else
192
+ field.class.new(property_by_name(field.target), field.operator)
193
+ end
194
+
195
+ when Symbol
196
+ property_by_name(field)
186
197
 
187
- case field
188
- when Query::Operator
189
- if field.target == :all
198
+ when Property
190
199
  field
191
- else
192
- field.class.new(property_by_name(field.target), field.operator)
193
- end
194
- when Symbol
195
- property_by_name(field)
196
- when Property
197
- field
200
+ end
198
201
  end
199
202
  end
200
203
  end
@@ -1,15 +1,17 @@
1
1
  module DataMapper
2
- class Collection
3
- include AggregateFunctions
2
+ module Aggregates
3
+ module Collection
4
+ include Functions
4
5
 
5
- # def size
6
- # loaded? ? super : count
7
- # end
6
+ # def size
7
+ # loaded? ? super : count
8
+ # end
8
9
 
9
- private
10
+ private
10
11
 
11
- def property_by_name(property_name)
12
- properties[property_name]
12
+ def property_by_name(property_name)
13
+ properties[property_name]
14
+ end
13
15
  end
14
16
  end
15
17
  end
@@ -0,0 +1,9 @@
1
+ class Symbol
2
+ [ :count, :min, :max, :avg, :sum ].each do |sym|
3
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
4
+ def #{sym}
5
+ DataMapper::Query::Operator.new(self, #{sym.inspect})
6
+ end
7
+ RUBY
8
+ end
9
+ end # class Symbol
@@ -1,15 +1,17 @@
1
1
  module DataMapper
2
- module Model
3
- include AggregateFunctions
2
+ module Aggregates
3
+ module Model
4
+ include Functions
4
5
 
5
- # def size
6
- # count
7
- # end
6
+ # def size
7
+ # count
8
+ # end
8
9
 
9
- private
10
+ private
10
11
 
11
- def property_by_name(property_name)
12
- properties(repository.name)[property_name]
12
+ def property_by_name(property_name)
13
+ properties(repository.name)[property_name]
14
+ end
13
15
  end
14
16
  end
15
17
  end
@@ -0,0 +1,27 @@
1
+ module DataMapper
2
+ module Aggregates
3
+ module Query
4
+ def self.included(base)
5
+ base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
6
+ # FIXME: figure out a cleaner approach than AMC
7
+ alias assert_valid_fields_without_operator assert_valid_fields
8
+ alias assert_valid_fields assert_valid_fields_with_operator
9
+ RUBY
10
+ end
11
+
12
+ def assert_valid_fields_with_operator(fields, unique)
13
+ operators, fields = fields.partition { |f| f.kind_of?(DataMapper::Query::Operator) }
14
+
15
+ operators.each do |operator|
16
+ target = operator.target
17
+
18
+ unless target == :all || target.kind_of?(Property) && target.model == model && @properties.include?(target)
19
+ raise ArgumentError, "+options[:fields]+ entry #{target.inspect} does not map to a property in #{model}"
20
+ end
21
+ end
22
+
23
+ assert_valid_fields_without_operator(fields, unique)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,7 +1,9 @@
1
1
  module DataMapper
2
- class Repository
3
- def aggregate(query)
4
- adapter.aggregate(query)
2
+ module Aggregates
3
+ module Repository
4
+ def aggregate(query)
5
+ adapter.aggregate(query)
6
+ end
5
7
  end
6
8
  end
7
9
  end
@@ -1,5 +1,5 @@
1
1
  module DataMapper
2
2
  module Aggregates
3
- VERSION = '0.9.11'
3
+ VERSION = '0.10.0'.freeze
4
4
  end
5
5
  end
data/lib/dm-aggregates.rb CHANGED
@@ -1,15 +1,26 @@
1
- require 'rubygems'
1
+ require 'dm-aggregates/adapters/data_objects_adapter'
2
+ require 'dm-aggregates/aggregate_functions'
3
+ require 'dm-aggregates/collection'
4
+ require 'dm-aggregates/core_ext/symbol'
5
+ require 'dm-aggregates/model'
6
+ require 'dm-aggregates/query'
7
+ require 'dm-aggregates/repository'
8
+ require 'dm-aggregates/version'
2
9
 
3
- dir = Pathname(__FILE__).dirname.expand_path + 'dm-aggregates'
10
+ module DataMapper
11
+ class Repository
12
+ include Aggregates::Repository
13
+ end
4
14
 
5
- require dir + 'version'
6
- gem 'dm-core', '0.9.11'
7
- require 'dm-core'
15
+ module Model
16
+ include Aggregates::Model
17
+ end
8
18
 
19
+ class Collection
20
+ include Aggregates::Collection
21
+ end
9
22
 
10
- require dir + 'aggregate_functions'
11
- require dir + 'model'
12
- require dir + 'repository'
13
- require dir + 'collection'
14
- require dir + 'adapters' + 'data_objects_adapter'
15
- require dir + 'support' + 'symbol'
23
+ class Query
24
+ include Aggregates::Query
25
+ end
26
+ end
@@ -1,5 +1,4 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
3
  if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
5
4
  describe DataMapper::Collection do
@@ -1,5 +1,4 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
3
  if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
5
4
  describe DataMapper::Model do
@@ -19,7 +19,7 @@ shared_examples_for 'It Has Setup Resources' do
19
19
  property :birth_on, Date
20
20
  property :birth_time, Time
21
21
 
22
- belongs_to :knight
22
+ belongs_to :knight, :nullable => true
23
23
  end
24
24
 
25
25
  # A more complex example, with BigDecimal and Float properties
data/spec/spec.opts CHANGED
@@ -1 +1,2 @@
1
1
  --colour
2
+ --loadby random
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,16 @@
1
- require 'pathname'
2
1
  require 'rubygems'
3
2
 
4
- SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
5
- require SPEC_ROOT.parent + 'lib/dm-aggregates'
6
- Pathname.glob((SPEC_ROOT + '{lib,*/shared}/**/*.rb').to_s).each { |f| require f }
3
+ # use local dm-core if running from a typical dev checkout.
4
+ lib = File.join('..', '..', 'dm-core', 'lib')
5
+ $LOAD_PATH.unshift(lib) if File.directory?(lib)
6
+ require 'dm-core'
7
+
8
+ # Support running specs with 'rake spec' and 'spec'
9
+ $LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
10
+
11
+ require 'dm-aggregates'
12
+
13
+ require 'public/shared/aggregate_shared_spec'
7
14
 
8
15
  def load_driver(name, default_uri)
9
16
  return false if ENV['ADAPTER'] != name.to_s
data/tasks/install.rb CHANGED
@@ -4,7 +4,7 @@ end
4
4
 
5
5
  desc "Install #{GEM_NAME} #{GEM_VERSION}"
6
6
  task :install => [ :package ] do
7
- sudo_gem "install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
7
+ sudo_gem "install pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
8
8
  end
9
9
 
10
10
  desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
data/tasks/spec.rb CHANGED
@@ -1,6 +1,4 @@
1
1
  begin
2
- gem 'rspec', '~>1.2'
3
- require 'spec'
4
2
  require 'spec/rake/spectask'
5
3
 
6
4
  task :default => [ :spec ]
@@ -8,16 +6,18 @@ begin
8
6
  desc 'Run specifications'
9
7
  Spec::Rake::SpecTask.new(:spec) do |t|
10
8
  t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
11
- t.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s).map { |f| f.to_s }
9
+ t.libs << 'lib' << 'spec' # needed for CI rake spec task, duplicated in spec_helper
12
10
 
13
11
  begin
14
- gem 'rcov', '~>0.8'
12
+ require 'rcov'
15
13
  t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
16
14
  t.rcov_opts << '--exclude' << 'spec'
17
15
  t.rcov_opts << '--text-summary'
18
16
  t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
19
17
  rescue LoadError
20
18
  # rcov not installed
19
+ rescue SyntaxError
20
+ # rcov syntax invalid
21
21
  end
22
22
  end
23
23
  rescue LoadError
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-aggregates
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.11
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foy Savas
@@ -9,19 +9,10 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-29 00:00:00 -07:00
12
+ date: 2009-09-16 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: dm-core
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - "="
22
- - !ruby/object:Gem::Version
23
- version: 0.9.11
24
- version:
14
+ dependencies: []
15
+
25
16
  description: DataMapper plugin providing support for aggregates, functions on collections and datasets
26
17
  email:
27
18
  - foysavas [a] gmail [d] com
@@ -30,24 +21,25 @@ executables: []
30
21
  extensions: []
31
22
 
32
23
  extra_rdoc_files:
33
- - README.txt
24
+ - README.rdoc
34
25
  - LICENSE
35
26
  - TODO
36
- - History.txt
27
+ - History.rdoc
37
28
  files:
38
- - History.txt
29
+ - History.rdoc
39
30
  - LICENSE
40
31
  - Manifest.txt
41
- - README.txt
32
+ - README.rdoc
42
33
  - Rakefile
43
34
  - TODO
44
35
  - lib/dm-aggregates.rb
45
36
  - lib/dm-aggregates/adapters/data_objects_adapter.rb
46
37
  - lib/dm-aggregates/aggregate_functions.rb
47
38
  - lib/dm-aggregates/collection.rb
39
+ - lib/dm-aggregates/core_ext/symbol.rb
48
40
  - lib/dm-aggregates/model.rb
41
+ - lib/dm-aggregates/query.rb
49
42
  - lib/dm-aggregates/repository.rb
50
- - lib/dm-aggregates/support/symbol.rb
51
43
  - lib/dm-aggregates/version.rb
52
44
  - spec/public/collection_spec.rb
53
45
  - spec/public/model_spec.rb
@@ -57,11 +49,13 @@ files:
57
49
  - tasks/install.rb
58
50
  - tasks/spec.rb
59
51
  has_rdoc: true
60
- homepage: http://github.com/sam/dm-more/tree/master/dm-aggregates
52
+ homepage: http://github.com/datamapper/dm-more/tree/master/dm-aggregates
53
+ licenses: []
54
+
61
55
  post_install_message:
62
56
  rdoc_options:
63
57
  - --main
64
- - README.txt
58
+ - README.rdoc
65
59
  require_paths:
66
60
  - lib
67
61
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -79,9 +73,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
73
  requirements: []
80
74
 
81
75
  rubyforge_project: datamapper
82
- rubygems_version: 1.3.1
76
+ rubygems_version: 1.3.5
83
77
  signing_key:
84
- specification_version: 2
78
+ specification_version: 3
85
79
  summary: DataMapper plugin providing support for aggregates, functions on collections and datasets
86
80
  test_files: []
87
81
 
@@ -1,21 +0,0 @@
1
- class Symbol
2
- def count
3
- DataMapper::Query::Operator.new(self, :count)
4
- end
5
-
6
- def min
7
- DataMapper::Query::Operator.new(self, :min)
8
- end
9
-
10
- def max
11
- DataMapper::Query::Operator.new(self, :max)
12
- end
13
-
14
- def avg
15
- DataMapper::Query::Operator.new(self, :avg)
16
- end
17
-
18
- def sum
19
- DataMapper::Query::Operator.new(self, :sum)
20
- end
21
- end # class Symbol