dm-aggregates 1.0.0.rc2 → 1.0.0.rc3
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/Gemfile +1 -1
- data/LICENSE +1 -1
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/dm-aggregates.gemspec +14 -8
- data/lib/dm-aggregates.rb +46 -13
- data/lib/dm-aggregates/adapters/{data_objects_adapter.rb → dm-do-adapter.rb} +21 -46
- data/spec/isolated/require_after_setup_spec.rb +21 -0
- data/spec/isolated/require_before_setup_spec.rb +21 -0
- data/spec/isolated/require_spec.rb +13 -0
- data/spec/rcov.opts +1 -1
- data/spec/spec_helper.rb +1 -0
- data/tasks/spec.rake +3 -0
- metadata +15 -9
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/Rakefile
CHANGED
@@ -10,12 +10,12 @@ begin
|
|
10
10
|
gem.summary = 'DataMapper plugin providing support for aggregates on collections'
|
11
11
|
gem.description = gem.summary
|
12
12
|
gem.email = 'foysavas [a] gmail [d] com'
|
13
|
-
gem.homepage = 'http://github.com/datamapper
|
13
|
+
gem.homepage = 'http://github.com/datamapper/%s' % gem.name
|
14
14
|
gem.authors = [ 'Foy Savas' ]
|
15
15
|
|
16
16
|
gem.rubyforge_project = 'datamapper'
|
17
17
|
|
18
|
-
gem.add_dependency 'dm-core', '~> 1.0.0.
|
18
|
+
gem.add_dependency 'dm-core', '~> 1.0.0.rc3'
|
19
19
|
|
20
20
|
gem.add_development_dependency 'rspec', '~> 1.3'
|
21
21
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0.
|
1
|
+
1.0.0.rc3
|
data/dm-aggregates.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dm-aggregates}
|
8
|
-
s.version = "1.0.0.
|
8
|
+
s.version = "1.0.0.rc3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Foy Savas"]
|
12
|
-
s.date = %q{2010-05-
|
12
|
+
s.date = %q{2010-05-27}
|
13
13
|
s.description = %q{DataMapper plugin providing support for aggregates on collections}
|
14
14
|
s.email = %q{foysavas [a] gmail [d] com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,13 +25,16 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"dm-aggregates.gemspec",
|
27
27
|
"lib/dm-aggregates.rb",
|
28
|
-
"lib/dm-aggregates/adapters/
|
28
|
+
"lib/dm-aggregates/adapters/dm-do-adapter.rb",
|
29
29
|
"lib/dm-aggregates/aggregate_functions.rb",
|
30
30
|
"lib/dm-aggregates/collection.rb",
|
31
31
|
"lib/dm-aggregates/core_ext/symbol.rb",
|
32
32
|
"lib/dm-aggregates/model.rb",
|
33
33
|
"lib/dm-aggregates/query.rb",
|
34
34
|
"lib/dm-aggregates/repository.rb",
|
35
|
+
"spec/isolated/require_after_setup_spec.rb",
|
36
|
+
"spec/isolated/require_before_setup_spec.rb",
|
37
|
+
"spec/isolated/require_spec.rb",
|
35
38
|
"spec/public/collection_spec.rb",
|
36
39
|
"spec/public/model_spec.rb",
|
37
40
|
"spec/public/shared/aggregate_shared_spec.rb",
|
@@ -45,14 +48,17 @@ Gem::Specification.new do |s|
|
|
45
48
|
"tasks/yard.rake",
|
46
49
|
"tasks/yardstick.rake"
|
47
50
|
]
|
48
|
-
s.homepage = %q{http://github.com/datamapper/dm-
|
51
|
+
s.homepage = %q{http://github.com/datamapper/dm-aggregates}
|
49
52
|
s.rdoc_options = ["--charset=UTF-8"]
|
50
53
|
s.require_paths = ["lib"]
|
51
54
|
s.rubyforge_project = %q{datamapper}
|
52
55
|
s.rubygems_version = %q{1.3.7}
|
53
56
|
s.summary = %q{DataMapper plugin providing support for aggregates on collections}
|
54
57
|
s.test_files = [
|
55
|
-
"spec/
|
58
|
+
"spec/isolated/require_after_setup_spec.rb",
|
59
|
+
"spec/isolated/require_before_setup_spec.rb",
|
60
|
+
"spec/isolated/require_spec.rb",
|
61
|
+
"spec/public/collection_spec.rb",
|
56
62
|
"spec/public/model_spec.rb",
|
57
63
|
"spec/public/shared/aggregate_shared_spec.rb",
|
58
64
|
"spec/spec_helper.rb"
|
@@ -63,14 +69,14 @@ Gem::Specification.new do |s|
|
|
63
69
|
s.specification_version = 3
|
64
70
|
|
65
71
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
66
|
-
s.add_runtime_dependency(%q<dm-core>, ["~> 1.0.0.
|
72
|
+
s.add_runtime_dependency(%q<dm-core>, ["~> 1.0.0.rc3"])
|
67
73
|
s.add_development_dependency(%q<rspec>, ["~> 1.3"])
|
68
74
|
else
|
69
|
-
s.add_dependency(%q<dm-core>, ["~> 1.0.0.
|
75
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0.rc3"])
|
70
76
|
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
71
77
|
end
|
72
78
|
else
|
73
|
-
s.add_dependency(%q<dm-core>, ["~> 1.0.0.
|
79
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0.rc3"])
|
74
80
|
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
75
81
|
end
|
76
82
|
end
|
data/lib/dm-aggregates.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'dm-core'
|
2
2
|
|
3
|
-
require 'dm-aggregates/adapters/data_objects_adapter'
|
4
3
|
require 'dm-aggregates/aggregate_functions'
|
5
4
|
require 'dm-aggregates/collection'
|
6
5
|
require 'dm-aggregates/core_ext/symbol'
|
@@ -15,19 +14,53 @@ rescue LoadError
|
|
15
14
|
end
|
16
15
|
|
17
16
|
module DataMapper
|
18
|
-
|
19
|
-
|
17
|
+
module Aggregates
|
18
|
+
def self.include_aggregate_api
|
19
|
+
[ :Repository, :Model, :Collection, :Query ].each do |name|
|
20
|
+
DataMapper.const_get(name).send(:include, const_get(name))
|
21
|
+
end
|
22
|
+
Adapters::AbstractAdapter.descendants.each do |adapter_class|
|
23
|
+
Adapters.include_aggregate_api(ActiveSupport::Inflector.demodulize(adapter_class.name))
|
24
|
+
end
|
25
|
+
end
|
20
26
|
end
|
21
27
|
|
22
|
-
module
|
23
|
-
include Aggregates::Model
|
24
|
-
end
|
28
|
+
module Adapters
|
25
29
|
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
def self.include_aggregate_api(const_name)
|
31
|
+
require aggregate_extensions(const_name)
|
32
|
+
if Aggregates.const_defined?(const_name)
|
33
|
+
adapter = const_get(const_name)
|
34
|
+
adapter.send(:include, aggregate_module(const_name))
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
# Silently ignore the fact that no adapter extensions could be required
|
38
|
+
# This means that the adapter in use doesn't support aggregates
|
39
|
+
end
|
29
40
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
41
|
+
def self.aggregate_module(const_name)
|
42
|
+
Aggregates.const_get(const_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
class << self
|
46
|
+
private
|
47
|
+
# @api private
|
48
|
+
def aggregate_extensions(const_name)
|
49
|
+
name = adapter_name(const_name)
|
50
|
+
name = 'do' if name == 'dataobjects'
|
51
|
+
"dm-aggregates/adapters/dm-#{name}-adapter"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
extendable do
|
56
|
+
# @api private
|
57
|
+
def const_added(const_name)
|
58
|
+
include_aggregate_api(const_name)
|
59
|
+
super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end # module Adapters
|
63
|
+
|
64
|
+
Aggregates.include_aggregate_api
|
65
|
+
|
66
|
+
end # module DataMapper
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module DataMapper
|
2
2
|
module Aggregates
|
3
3
|
module DataObjectsAdapter
|
4
|
-
|
5
|
-
base.send(:include, SQL)
|
6
|
-
end
|
4
|
+
extend Chainable
|
7
5
|
|
8
6
|
def aggregate(query)
|
9
7
|
fields = query.fields
|
@@ -63,63 +61,40 @@ module DataMapper
|
|
63
61
|
property.load(value)
|
64
62
|
end
|
65
63
|
|
66
|
-
|
67
|
-
def
|
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
|
74
|
-
|
75
|
-
def property_to_column_name_with_operator(property, qualify)
|
64
|
+
chainable do
|
65
|
+
def property_to_column_name(property, qualify)
|
76
66
|
case property
|
77
67
|
when DataMapper::Query::Operator
|
78
68
|
aggregate_field_statement(property.operator, property.target, qualify)
|
79
69
|
|
80
70
|
when Property, DataMapper::Query::Path
|
81
|
-
|
71
|
+
super
|
82
72
|
|
83
73
|
else
|
84
74
|
raise ArgumentError, "+property+ must be a DataMapper::Query::Operator, a DataMapper::Property or a Query::Path, but was a #{property.class} (#{property.inspect})"
|
85
75
|
end
|
86
76
|
end
|
77
|
+
end
|
87
78
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
function_name = case aggregate_function
|
96
|
-
when :count then 'COUNT'
|
97
|
-
when :min then 'MIN'
|
98
|
-
when :max then 'MAX'
|
99
|
-
when :avg then 'AVG'
|
100
|
-
when :sum then 'SUM'
|
101
|
-
else raise "Invalid aggregate function: #{aggregate_function.inspect}"
|
102
|
-
end
|
103
|
-
|
104
|
-
"#{function_name}(#{column_name})"
|
79
|
+
def aggregate_field_statement(aggregate_function, property, qualify)
|
80
|
+
column_name = if aggregate_function == :count && property == :all
|
81
|
+
'*'
|
82
|
+
else
|
83
|
+
property_to_column_name(property, qualify)
|
105
84
|
end
|
106
|
-
end # module SQL
|
107
|
-
end # class DataObjectsAdapter
|
108
|
-
end # module Aggregates
|
109
|
-
|
110
|
-
module Adapters
|
111
|
-
extendable do
|
112
85
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
86
|
+
function_name = case aggregate_function
|
87
|
+
when :count then 'COUNT'
|
88
|
+
when :min then 'MIN'
|
89
|
+
when :max then 'MAX'
|
90
|
+
when :avg then 'AVG'
|
91
|
+
when :sum then 'SUM'
|
92
|
+
else raise "Invalid aggregate function: #{aggregate_function.inspect}"
|
119
93
|
end
|
120
94
|
|
121
|
-
|
95
|
+
"#{function_name}(#{column_name})"
|
122
96
|
end
|
123
|
-
|
124
|
-
|
97
|
+
|
98
|
+
end # class DataObjectsAdapter
|
99
|
+
end # module Aggregates
|
125
100
|
end # module DataMapper
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'isolated/require_spec'
|
3
|
+
require 'dm-core/spec/setup'
|
4
|
+
|
5
|
+
# To really test this behavior, this spec needs to be run in isolation and not
|
6
|
+
# as part of the typical rake spec run, which requires dm-aggregates upfront
|
7
|
+
|
8
|
+
if %w[ postgres mysql sqlite oracle sqlserver ].include?(ENV['ADAPTER'])
|
9
|
+
|
10
|
+
describe "require 'dm-aggregates after calling DataMapper.setup" do
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
@adapter = DataMapper::Spec.adapter
|
14
|
+
require 'dm-aggregates'
|
15
|
+
end
|
16
|
+
|
17
|
+
it_should_behave_like "require 'dm-aggregates'"
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'isolated/require_spec'
|
3
|
+
require 'dm-core/spec/setup'
|
4
|
+
|
5
|
+
# To really test this behavior, this spec needs to be run in isolation and not
|
6
|
+
# as part of the typical rake spec run, which requires dm-aggregates upfront
|
7
|
+
|
8
|
+
if %w[ postgres mysql sqlite oracle sqlserver ].include?(ENV['ADAPTER'])
|
9
|
+
|
10
|
+
describe "require 'dm-aggregates' before calling DataMapper.setup" do
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
require 'dm-aggregates'
|
14
|
+
@adapter = DataMapper::Spec.adapter
|
15
|
+
end
|
16
|
+
|
17
|
+
it_should_behave_like "require 'dm-aggregates'"
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
shared_examples_for "require 'dm-aggregates'" do
|
2
|
+
|
3
|
+
%w[ Repository Model Collection Query ].each do |name|
|
4
|
+
it "should include the aggregate api in DataMapper::#{name}" do
|
5
|
+
(DataMapper.const_get(name) < DataMapper::Aggregates.const_get(name)).should be(true)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should include the aggregate api into the adapter" do
|
10
|
+
@adapter.respond_to?(:aggregate).should be(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
data/spec/rcov.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
data/tasks/spec.rake
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-aggregates
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 977940572
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
9
|
- 0
|
10
|
-
-
|
11
|
-
version: 1.0.0.
|
10
|
+
- rc3
|
11
|
+
version: 1.0.0.rc3
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Foy Savas
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-05-
|
19
|
+
date: 2010-05-27 00:00:00 -07:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -27,13 +27,13 @@ dependencies:
|
|
27
27
|
requirements:
|
28
28
|
- - ~>
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
hash:
|
30
|
+
hash: 977940572
|
31
31
|
segments:
|
32
32
|
- 1
|
33
33
|
- 0
|
34
34
|
- 0
|
35
|
-
-
|
36
|
-
version: 1.0.0.
|
35
|
+
- rc3
|
36
|
+
version: 1.0.0.rc3
|
37
37
|
type: :runtime
|
38
38
|
version_requirements: *id001
|
39
39
|
- !ruby/object:Gem::Dependency
|
@@ -69,13 +69,16 @@ files:
|
|
69
69
|
- VERSION
|
70
70
|
- dm-aggregates.gemspec
|
71
71
|
- lib/dm-aggregates.rb
|
72
|
-
- lib/dm-aggregates/adapters/
|
72
|
+
- lib/dm-aggregates/adapters/dm-do-adapter.rb
|
73
73
|
- lib/dm-aggregates/aggregate_functions.rb
|
74
74
|
- lib/dm-aggregates/collection.rb
|
75
75
|
- lib/dm-aggregates/core_ext/symbol.rb
|
76
76
|
- lib/dm-aggregates/model.rb
|
77
77
|
- lib/dm-aggregates/query.rb
|
78
78
|
- lib/dm-aggregates/repository.rb
|
79
|
+
- spec/isolated/require_after_setup_spec.rb
|
80
|
+
- spec/isolated/require_before_setup_spec.rb
|
81
|
+
- spec/isolated/require_spec.rb
|
79
82
|
- spec/public/collection_spec.rb
|
80
83
|
- spec/public/model_spec.rb
|
81
84
|
- spec/public/shared/aggregate_shared_spec.rb
|
@@ -89,7 +92,7 @@ files:
|
|
89
92
|
- tasks/yard.rake
|
90
93
|
- tasks/yardstick.rake
|
91
94
|
has_rdoc: true
|
92
|
-
homepage: http://github.com/datamapper/dm-
|
95
|
+
homepage: http://github.com/datamapper/dm-aggregates
|
93
96
|
licenses: []
|
94
97
|
|
95
98
|
post_install_message:
|
@@ -125,6 +128,9 @@ signing_key:
|
|
125
128
|
specification_version: 3
|
126
129
|
summary: DataMapper plugin providing support for aggregates on collections
|
127
130
|
test_files:
|
131
|
+
- spec/isolated/require_after_setup_spec.rb
|
132
|
+
- spec/isolated/require_before_setup_spec.rb
|
133
|
+
- spec/isolated/require_spec.rb
|
128
134
|
- spec/public/collection_spec.rb
|
129
135
|
- spec/public/model_spec.rb
|
130
136
|
- spec/public/shared/aggregate_shared_spec.rb
|