by_star 2.2.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +5 -5
- data/.travis.yml +61 -35
- data/CHANGELOG.md +44 -35
- data/Gemfile +18 -25
- data/MIT-LICENSE +20 -20
- data/README.md +577 -540
- data/Rakefile +18 -18
- data/UPGRADING +6 -12
- data/by_star.gemspec +34 -32
- data/cleaner.rb +24 -24
- data/lib/by_star.rb +17 -16
- data/lib/by_star/base.rb +68 -70
- data/lib/by_star/between.rb +156 -120
- data/lib/by_star/directional.rb +37 -33
- data/lib/by_star/kernel/date.rb +50 -19
- data/lib/by_star/kernel/time.rb +41 -41
- data/lib/by_star/normalization.rb +127 -118
- data/lib/by_star/orm/active_record/by_star.rb +61 -69
- data/lib/by_star/orm/mongoid/by_star.rb +76 -73
- data/lib/by_star/orm/mongoid/reorder.rb +23 -0
- data/lib/by_star/version.rb +3 -3
- data/spec/database.yml +15 -15
- data/spec/fixtures/active_record/models.rb +12 -10
- data/spec/fixtures/active_record/schema.rb +19 -19
- data/spec/fixtures/mongoid/models.rb +31 -29
- data/spec/fixtures/shared/seeds.rb +26 -26
- data/spec/gemfiles/Gemfile.master +6 -0
- data/spec/gemfiles/Gemfile.rails40 +7 -0
- data/spec/gemfiles/Gemfile.rails41 +7 -0
- data/spec/gemfiles/Gemfile.rails42 +7 -0
- data/spec/gemfiles/Gemfile.rails50 +10 -0
- data/spec/gemfiles/Gemfile.rails51 +10 -0
- data/spec/integration/active_record/active_record_spec.rb +38 -53
- data/spec/integration/mongoid/mongoid_spec.rb +37 -46
- data/spec/integration/shared/between_times.rb +82 -0
- data/spec/integration/shared/by_calendar_month.rb +55 -55
- data/spec/integration/shared/by_cweek.rb +54 -0
- data/spec/integration/shared/by_day.rb +96 -108
- data/spec/integration/shared/by_direction.rb +172 -153
- data/spec/integration/shared/by_fortnight.rb +48 -48
- data/spec/integration/shared/by_month.rb +50 -50
- data/spec/integration/shared/by_quarter.rb +49 -49
- data/spec/integration/shared/by_week.rb +54 -54
- data/spec/integration/shared/by_weekend.rb +49 -49
- data/spec/integration/shared/by_year.rb +48 -48
- data/spec/integration/shared/offset_parameter.rb +32 -31
- data/spec/integration/shared/order_parameter.rb +36 -0
- data/spec/integration/shared/relative.rb +174 -174
- data/spec/integration/shared/scope_parameter.rb +73 -72
- data/spec/spec_helper.rb +29 -29
- data/spec/unit/kernel_date_spec.rb +113 -60
- data/spec/unit/kernel_time_spec.rb +57 -57
- data/spec/unit/normalization_spec.rb +305 -255
- metadata +61 -62
@@ -1,69 +1,61 @@
|
|
1
|
-
module ByStar
|
2
|
-
module ActiveRecord
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
module ClassMethods
|
6
|
-
include ::ByStar::Base
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
scope
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
field
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
def next(options={})
|
64
|
-
field = self.class.by_star_start_field
|
65
|
-
value = self.send(field.split(".").last)
|
66
|
-
self.class.by_star_scope(options.merge(scope_args: self)).where("#{field} > ?", value).reorder("#{field} ASC").first
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
1
|
+
module ByStar
|
2
|
+
module ActiveRecord
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
include ::ByStar::Base
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def by_star_default_field
|
11
|
+
"#{self.table_name}.created_at"
|
12
|
+
end
|
13
|
+
|
14
|
+
def by_star_point_query(scope, field, start_time, end_time)
|
15
|
+
scope.where("#{field} >= ? AND #{field} <= ?", start_time, end_time)
|
16
|
+
end
|
17
|
+
|
18
|
+
def by_star_span_strict_query(scope, start_field, end_field, start_time, end_time)
|
19
|
+
scope.where("#{start_field} >= ? AND #{start_field} <= ? AND #{end_field} >= ? AND #{end_field} <= ?", start_time, end_time, start_time, end_time)
|
20
|
+
end
|
21
|
+
|
22
|
+
def by_star_span_overlap_query(scope, start_field, end_field, start_time, end_time, options)
|
23
|
+
scope.where("#{end_field} > ? AND #{start_field} < ?", start_time, end_time)
|
24
|
+
end
|
25
|
+
|
26
|
+
def by_star_before_query(scope, field, time)
|
27
|
+
scope.where("#{field} <= ?", time)
|
28
|
+
end
|
29
|
+
|
30
|
+
def by_star_after_query(scope, field, time)
|
31
|
+
scope.where("#{field} >= ?", time)
|
32
|
+
end
|
33
|
+
|
34
|
+
def by_star_order(scope, order)
|
35
|
+
scope.order(order)
|
36
|
+
end
|
37
|
+
|
38
|
+
def oldest_query(options={})
|
39
|
+
field = by_star_start_field(options)
|
40
|
+
by_star_scope(options).reorder("#{field} ASC").first
|
41
|
+
end
|
42
|
+
|
43
|
+
def newest_query(options={})
|
44
|
+
field = by_star_start_field(options)
|
45
|
+
by_star_scope(options).reorder("#{field} DESC").first
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def previous(options={})
|
50
|
+
field = self.class.by_star_start_field(options)
|
51
|
+
value = self.send(field.split(".").last)
|
52
|
+
self.class.by_star_scope(options.merge(scope_args: self)).where("#{field} < ?", value).reorder("#{field} DESC").first
|
53
|
+
end
|
54
|
+
|
55
|
+
def next(options={})
|
56
|
+
field = self.class.by_star_start_field(options)
|
57
|
+
value = self.send(field.split(".").last)
|
58
|
+
self.class.by_star_scope(options.merge(scope_args: self)).where("#{field} > ?", value).reorder("#{field} ASC").first
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,73 +1,76 @@
|
|
1
|
-
# In keeping with Mongoid standards, this module must be included into your model class, i.e.
|
2
|
-
#
|
3
|
-
# include Mongoid::ByStar
|
4
|
-
#
|
5
|
-
module Mongoid
|
6
|
-
module ByStar
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
include ::ByStar::Base
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def
|
48
|
-
field
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
1
|
+
# In keeping with Mongoid standards, this module must be included into your model class, i.e.
|
2
|
+
#
|
3
|
+
# include Mongoid::ByStar
|
4
|
+
#
|
5
|
+
module Mongoid
|
6
|
+
module ByStar
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
include ::ByStar::Base
|
11
|
+
|
12
|
+
alias_method :original_by_star_end_field, :by_star_end_field
|
13
|
+
alias_method :original_by_star_start_field, :by_star_start_field
|
14
|
+
|
15
|
+
def by_star_end_field(options = {})
|
16
|
+
database_field_name original_by_star_end_field(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def by_star_start_field(options = {})
|
20
|
+
database_field_name original_by_star_start_field(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def by_star_default_field
|
24
|
+
:created_at
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def by_star_point_query(scope, field, start_time, end_time)
|
30
|
+
range = start_time..end_time
|
31
|
+
scope.where(field => range)
|
32
|
+
end
|
33
|
+
|
34
|
+
def by_star_span_strict_query(scope, start_field, end_field, start_time, end_time)
|
35
|
+
range = start_time..end_time
|
36
|
+
scope.where(start_field => range).where(end_field => range)
|
37
|
+
end
|
38
|
+
|
39
|
+
def by_star_span_overlap_query(scope, start_field, end_field, start_time, end_time, options)
|
40
|
+
scope.gt(end_field => start_time).lt(start_field => end_time)
|
41
|
+
end
|
42
|
+
|
43
|
+
def by_star_before_query(scope, field, time)
|
44
|
+
scope.lte(field => time)
|
45
|
+
end
|
46
|
+
|
47
|
+
def by_star_after_query(scope, field, time)
|
48
|
+
scope.gte(field => time)
|
49
|
+
end
|
50
|
+
|
51
|
+
def by_star_order(scope, order)
|
52
|
+
scope.order_by(order)
|
53
|
+
end
|
54
|
+
|
55
|
+
def oldest_query(options={})
|
56
|
+
field = by_star_start_field(options)
|
57
|
+
by_star_scope(options).all.reorder(field => :asc).first
|
58
|
+
end
|
59
|
+
|
60
|
+
def newest_query(options={})
|
61
|
+
field = by_star_start_field(options)
|
62
|
+
by_star_scope(options).all.reorder(field => :desc).first
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def previous(options={})
|
67
|
+
field = self.class.by_star_start_field(options)
|
68
|
+
self.class.by_star_scope(options.merge(scope_args: self)).lt(field => self.send(field)).reorder(field => :desc).first
|
69
|
+
end
|
70
|
+
|
71
|
+
def next(options={})
|
72
|
+
field = self.class.by_star_start_field(options)
|
73
|
+
self.class.by_star_scope(options.merge(scope_args: self)).gt(field => self.send(field)).reorder(field => :asc).first
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Backport of `reorder` method from Origin 2.1.0+
|
2
|
+
if defined?(Origin::Optional) && !Origin::Optional.method_defined?(:reorder)
|
3
|
+
module Origin
|
4
|
+
module Optional
|
5
|
+
|
6
|
+
# Instead of merging the order criteria, use this method to completely
|
7
|
+
# replace the existing ordering with the provided.
|
8
|
+
#
|
9
|
+
# @example Replace the ordering.
|
10
|
+
# optional.reorder(name: :asc)
|
11
|
+
#
|
12
|
+
# @param [ Array, Hash, String ] spec The sorting specification.
|
13
|
+
#
|
14
|
+
# @return [ Optional ] The cloned optional.
|
15
|
+
#
|
16
|
+
# @since 2.1.0
|
17
|
+
def reorder(*spec)
|
18
|
+
options.delete(:sort)
|
19
|
+
order_by(*spec)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/by_star/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module ByStar
|
2
|
-
VERSION = '
|
3
|
-
end
|
1
|
+
module ByStar
|
2
|
+
VERSION = '3.0.0'
|
3
|
+
end
|
data/spec/database.yml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
sqlite:
|
2
|
-
adapter: sqlite3
|
3
|
-
database: by_star.sqlite3
|
4
|
-
|
5
|
-
postgres:
|
6
|
-
adapter: postgresql
|
7
|
-
database: by_star_test
|
8
|
-
username: postgres
|
9
|
-
min_messages: warning
|
10
|
-
|
11
|
-
mysql:
|
12
|
-
adapter: mysql2
|
13
|
-
database: by_star_test
|
14
|
-
username: root
|
15
|
-
encoding: utf8
|
1
|
+
sqlite:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: by_star.sqlite3
|
4
|
+
|
5
|
+
postgres:
|
6
|
+
adapter: postgresql
|
7
|
+
database: by_star_test
|
8
|
+
username: postgres
|
9
|
+
min_messages: warning
|
10
|
+
|
11
|
+
mysql:
|
12
|
+
adapter: mysql2
|
13
|
+
database: by_star_test
|
14
|
+
username: root
|
15
|
+
encoding: utf8
|
@@ -1,10 +1,12 @@
|
|
1
|
-
class Post < ActiveRecord::Base
|
2
|
-
end
|
3
|
-
|
4
|
-
class Appointment < ActiveRecord::Base
|
5
|
-
by_star_field scope: ->{ where(day_of_month: 1) }
|
6
|
-
end
|
7
|
-
|
8
|
-
class Event < ActiveRecord::Base
|
9
|
-
by_star_field :start_time, :end_time, offset: 3.hours
|
10
|
-
|
1
|
+
class Post < ActiveRecord::Base
|
2
|
+
end
|
3
|
+
|
4
|
+
class Appointment < ActiveRecord::Base
|
5
|
+
by_star_field scope: ->{ where(day_of_month: 1) }
|
6
|
+
end
|
7
|
+
|
8
|
+
class Event < ActiveRecord::Base
|
9
|
+
by_star_field :start_time, :end_time, offset: 3.hours
|
10
|
+
|
11
|
+
default_scope ->{ order(day_of_month: :asc) }
|
12
|
+
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
ActiveRecord::Schema.define do
|
2
|
-
self.verbose = false
|
3
|
-
|
4
|
-
create_table :posts, :
|
5
|
-
t.timestamps
|
6
|
-
t.integer :day_of_month
|
7
|
-
end
|
8
|
-
|
9
|
-
create_table :events, :
|
10
|
-
t.timestamps
|
11
|
-
t.datetime :start_time, :end_time
|
12
|
-
t.integer :day_of_month
|
13
|
-
end
|
14
|
-
|
15
|
-
create_table :appointments, :
|
16
|
-
t.timestamps
|
17
|
-
t.integer :day_of_month
|
18
|
-
end
|
19
|
-
end
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
self.verbose = false
|
3
|
+
|
4
|
+
create_table :posts, force: true do |t|
|
5
|
+
t.timestamps
|
6
|
+
t.integer :day_of_month
|
7
|
+
end
|
8
|
+
|
9
|
+
create_table :events, force: true do |t|
|
10
|
+
t.timestamps
|
11
|
+
t.datetime :start_time, :end_time
|
12
|
+
t.integer :day_of_month
|
13
|
+
end
|
14
|
+
|
15
|
+
create_table :appointments, force: true do |t|
|
16
|
+
t.timestamps
|
17
|
+
t.integer :day_of_month
|
18
|
+
end
|
19
|
+
end
|
@@ -1,29 +1,31 @@
|
|
1
|
-
class Post
|
2
|
-
include Mongoid::Document
|
3
|
-
include Mongoid::Timestamps
|
4
|
-
include Mongoid::ByStar
|
5
|
-
|
6
|
-
field :day_of_month, type: Integer
|
7
|
-
end
|
8
|
-
|
9
|
-
class Appointment
|
10
|
-
include Mongoid::Document
|
11
|
-
include Mongoid::Timestamps
|
12
|
-
include Mongoid::ByStar
|
13
|
-
|
14
|
-
field :day_of_month, type: Integer
|
15
|
-
|
16
|
-
by_star_field scope: ->{ where(day_of_month: 1) }
|
17
|
-
end
|
18
|
-
|
19
|
-
class Event
|
20
|
-
include Mongoid::Document
|
21
|
-
include Mongoid::Timestamps
|
22
|
-
include Mongoid::ByStar
|
23
|
-
|
24
|
-
field :st, as: :start_time, type: Time
|
25
|
-
field :end_time, type: Time
|
26
|
-
field :day_of_month, type: Integer
|
27
|
-
|
28
|
-
by_star_field :start_time, :end_time, offset: 3.hours
|
29
|
-
|
1
|
+
class Post
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Timestamps
|
4
|
+
include Mongoid::ByStar
|
5
|
+
|
6
|
+
field :day_of_month, type: Integer
|
7
|
+
end
|
8
|
+
|
9
|
+
class Appointment
|
10
|
+
include Mongoid::Document
|
11
|
+
include Mongoid::Timestamps
|
12
|
+
include Mongoid::ByStar
|
13
|
+
|
14
|
+
field :day_of_month, type: Integer
|
15
|
+
|
16
|
+
by_star_field scope: ->{ where(day_of_month: 1) }
|
17
|
+
end
|
18
|
+
|
19
|
+
class Event
|
20
|
+
include Mongoid::Document
|
21
|
+
include Mongoid::Timestamps
|
22
|
+
include Mongoid::ByStar
|
23
|
+
|
24
|
+
field :st, as: :start_time, type: Time
|
25
|
+
field :end_time, type: Time
|
26
|
+
field :day_of_month, type: Integer
|
27
|
+
|
28
|
+
by_star_field :start_time, :end_time, offset: 3.hours
|
29
|
+
|
30
|
+
default_scope ->{ order_by(day_of_month: :asc) }
|
31
|
+
end
|