groupdate 3.2.0 → 6.2.1
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +146 -27
- data/CONTRIBUTING.md +75 -0
- data/LICENSE.txt +1 -1
- data/README.md +67 -44
- data/lib/groupdate/active_record.rb +4 -51
- data/lib/groupdate/adapters/base_adapter.rb +51 -0
- data/lib/groupdate/adapters/mysql_adapter.rb +63 -0
- data/lib/groupdate/adapters/postgresql_adapter.rb +46 -0
- data/lib/groupdate/adapters/sqlite_adapter.rb +51 -0
- data/lib/groupdate/enumerable.rb +9 -14
- data/lib/groupdate/magic.rb +202 -333
- data/lib/groupdate/query_methods.rb +18 -0
- data/lib/groupdate/relation.rb +19 -0
- data/lib/groupdate/series_builder.rb +304 -0
- data/lib/groupdate/version.rb +1 -1
- data/lib/groupdate.rb +37 -7
- metadata +20 -145
- data/.gitignore +0 -19
- data/.travis.yml +0 -25
- data/Gemfile +0 -6
- data/Rakefile +0 -24
- data/groupdate.gemspec +0 -37
- data/lib/groupdate/calculations.rb +0 -26
- data/lib/groupdate/order_hack.rb +0 -11
- data/lib/groupdate/scopes.rb +0 -24
- data/lib/groupdate/series.rb +0 -30
- data/test/enumerable_test.rb +0 -60
- data/test/gemfiles/activerecord31.gemfile +0 -6
- data/test/gemfiles/activerecord32.gemfile +0 -6
- data/test/gemfiles/activerecord40.gemfile +0 -6
- data/test/gemfiles/activerecord41.gemfile +0 -6
- data/test/gemfiles/activerecord42.gemfile +0 -6
- data/test/gemfiles/redshift.gemfile +0 -7
- data/test/mysql_test.rb +0 -15
- data/test/postgresql_test.rb +0 -15
- data/test/redshift_test.rb +0 -18
- data/test/sqlite_test.rb +0 -29
- data/test/test_helper.rb +0 -1207
@@ -1,26 +0,0 @@
|
|
1
|
-
module Groupdate
|
2
|
-
class Calculations
|
3
|
-
attr_reader :relation
|
4
|
-
|
5
|
-
def initialize(relation)
|
6
|
-
@relation = relation
|
7
|
-
end
|
8
|
-
|
9
|
-
def include?(method)
|
10
|
-
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb
|
11
|
-
ActiveRecord::Calculations.method_defined?(method) || custom_calculations.include?(method)
|
12
|
-
end
|
13
|
-
|
14
|
-
def custom_calculations
|
15
|
-
return [] if !model.respond_to?(:groupdate_calculation_methods)
|
16
|
-
model.groupdate_calculation_methods
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def model
|
22
|
-
return if !relation.respond_to?(:klass)
|
23
|
-
relation.klass
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/groupdate/order_hack.rb
DELETED
data/lib/groupdate/scopes.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
module Groupdate
|
2
|
-
module Scopes
|
3
|
-
Groupdate::PERIODS.each do |period|
|
4
|
-
define_method :"group_by_#{period}" do |field, *args|
|
5
|
-
args = args.dup
|
6
|
-
options = args[-1].is_a?(Hash) ? args.pop : {}
|
7
|
-
options[:time_zone] ||= args[0] unless args[0].nil?
|
8
|
-
options[:range] ||= args[1] unless args[1].nil?
|
9
|
-
|
10
|
-
Groupdate::Magic.new(period, options).relation(field, self)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def group_by_period(period, field, options = {})
|
15
|
-
# to_sym is unsafe on user input, so convert to strings
|
16
|
-
permitted_periods = ((options[:permit] || Groupdate::PERIODS).map(&:to_sym) & Groupdate::PERIODS).map(&:to_s)
|
17
|
-
if permitted_periods.include?(period.to_s)
|
18
|
-
send("group_by_#{period}", field, options)
|
19
|
-
else
|
20
|
-
raise ArgumentError, "Unpermitted period"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/lib/groupdate/series.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module Groupdate
|
2
|
-
class Series
|
3
|
-
attr_accessor :magic, :relation
|
4
|
-
|
5
|
-
def initialize(magic, relation)
|
6
|
-
@magic = magic
|
7
|
-
@relation = relation
|
8
|
-
@calculations = Groupdate::Calculations.new(relation)
|
9
|
-
end
|
10
|
-
|
11
|
-
# clone to prevent modifying original variables
|
12
|
-
def method_missing(method, *args, &block)
|
13
|
-
if @calculations.include?(method)
|
14
|
-
magic.perform(relation, method, *args, &block)
|
15
|
-
elsif relation.respond_to?(method, true)
|
16
|
-
Groupdate::Series.new(magic, relation.send(method, *args, &block))
|
17
|
-
else
|
18
|
-
super
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def respond_to?(method, include_all = false)
|
23
|
-
@calculations.include?(method) || relation.respond_to?(method) || super
|
24
|
-
end
|
25
|
-
|
26
|
-
def reverse_order_value
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/test/enumerable_test.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require_relative "test_helper"
|
2
|
-
require "ostruct"
|
3
|
-
|
4
|
-
class EnumerableTest < Minitest::Test
|
5
|
-
include TestGroupdate
|
6
|
-
|
7
|
-
def test_enumerable
|
8
|
-
user_a = create_user("2014-01-21")
|
9
|
-
user_b = create_user("2014-03-14")
|
10
|
-
expected = {
|
11
|
-
Date.parse("2014-01-01") => [user_a],
|
12
|
-
Date.parse("2014-03-01") => [user_b]
|
13
|
-
}
|
14
|
-
assert_equal expected, [user_a, user_b].group_by_month(&:created_at)
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_enumerable_series
|
18
|
-
user_a = create_user("2014-01-21")
|
19
|
-
user_b = create_user("2014-03-14")
|
20
|
-
expected = {
|
21
|
-
Date.parse("2014-01-01") => [user_a],
|
22
|
-
Date.parse("2014-02-01") => [],
|
23
|
-
Date.parse("2014-03-01") => [user_b]
|
24
|
-
}
|
25
|
-
assert_equal expected, [user_a, user_b].group_by_month(series: true, &:created_at)
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_no_block
|
29
|
-
assert_raises(ArgumentError) { [].group_by_day(:created_at) }
|
30
|
-
end
|
31
|
-
|
32
|
-
def call_method(method, field, options)
|
33
|
-
Hash[@users.group_by_period(method, options) { |u| u.send(field) }.map { |k, v| [k, v.size] }]
|
34
|
-
end
|
35
|
-
|
36
|
-
def create_user(created_at, score = 1)
|
37
|
-
user =
|
38
|
-
OpenStruct.new(
|
39
|
-
name: "Andrew",
|
40
|
-
score: score,
|
41
|
-
created_at: created_at ? utc.parse(created_at) : nil,
|
42
|
-
created_on: created_at ? Date.parse(created_at) : nil
|
43
|
-
)
|
44
|
-
@users << user
|
45
|
-
user
|
46
|
-
end
|
47
|
-
|
48
|
-
def setup
|
49
|
-
super
|
50
|
-
@users = []
|
51
|
-
end
|
52
|
-
|
53
|
-
def teardown
|
54
|
-
# do nothing
|
55
|
-
end
|
56
|
-
|
57
|
-
def enumerable_test?
|
58
|
-
true
|
59
|
-
end
|
60
|
-
end
|
data/test/mysql_test.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require_relative "test_helper"
|
2
|
-
|
3
|
-
class MysqlTest < Minitest::Test
|
4
|
-
include TestGroupdate
|
5
|
-
include TestDatabase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
super
|
9
|
-
@@setup ||= begin
|
10
|
-
ActiveRecord::Base.establish_connection adapter: "mysql2", database: "groupdate_test", username: "root"
|
11
|
-
create_tables
|
12
|
-
true
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/test/postgresql_test.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require_relative "test_helper"
|
2
|
-
|
3
|
-
class PostgresqlTest < Minitest::Test
|
4
|
-
include TestGroupdate
|
5
|
-
include TestDatabase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
super
|
9
|
-
@@setup ||= begin
|
10
|
-
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "groupdate_test"
|
11
|
-
create_tables
|
12
|
-
true
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/test/redshift_test.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative "test_helper"
|
2
|
-
|
3
|
-
class RedshiftTest < Minitest::Test
|
4
|
-
include TestGroupdate
|
5
|
-
include TestDatabase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
super
|
9
|
-
@@setup ||= begin
|
10
|
-
abort("REDSHIFT_URL environment variable must be set in order to run tests") unless ENV["REDSHIFT_URL"].present?
|
11
|
-
|
12
|
-
ActiveRecord::Base.establish_connection(ENV["REDSHIFT_URL"])
|
13
|
-
|
14
|
-
create_redshift_tables
|
15
|
-
true
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/test/sqlite_test.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require_relative "test_helper"
|
2
|
-
|
3
|
-
class TestSqlite < Minitest::Test
|
4
|
-
include TestGroupdate
|
5
|
-
include TestDatabase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
super
|
9
|
-
@@setup ||= begin
|
10
|
-
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
11
|
-
create_tables
|
12
|
-
true
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_where_after
|
17
|
-
skip
|
18
|
-
end
|
19
|
-
|
20
|
-
def call_method(method, field, options)
|
21
|
-
if method == :quarter || options[:time_zone] || options[:day_start] || options[:week_start] || Groupdate.week_start != :sun || (Time.zone && options[:time_zone] != false)
|
22
|
-
error = assert_raises(Groupdate::Error) { super }
|
23
|
-
assert_includes error.message, "not supported for SQLite"
|
24
|
-
skip # after assertions
|
25
|
-
else
|
26
|
-
super
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|