by_star 2.2.1 → 3.0.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.
Files changed (55) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +5 -5
  3. data/.travis.yml +61 -35
  4. data/CHANGELOG.md +44 -35
  5. data/Gemfile +18 -25
  6. data/MIT-LICENSE +20 -20
  7. data/README.md +577 -540
  8. data/Rakefile +18 -18
  9. data/UPGRADING +6 -12
  10. data/by_star.gemspec +34 -32
  11. data/cleaner.rb +24 -24
  12. data/lib/by_star.rb +17 -16
  13. data/lib/by_star/base.rb +68 -70
  14. data/lib/by_star/between.rb +156 -120
  15. data/lib/by_star/directional.rb +37 -33
  16. data/lib/by_star/kernel/date.rb +50 -19
  17. data/lib/by_star/kernel/time.rb +41 -41
  18. data/lib/by_star/normalization.rb +127 -118
  19. data/lib/by_star/orm/active_record/by_star.rb +61 -69
  20. data/lib/by_star/orm/mongoid/by_star.rb +76 -73
  21. data/lib/by_star/orm/mongoid/reorder.rb +23 -0
  22. data/lib/by_star/version.rb +3 -3
  23. data/spec/database.yml +15 -15
  24. data/spec/fixtures/active_record/models.rb +12 -10
  25. data/spec/fixtures/active_record/schema.rb +19 -19
  26. data/spec/fixtures/mongoid/models.rb +31 -29
  27. data/spec/fixtures/shared/seeds.rb +26 -26
  28. data/spec/gemfiles/Gemfile.master +6 -0
  29. data/spec/gemfiles/Gemfile.rails40 +7 -0
  30. data/spec/gemfiles/Gemfile.rails41 +7 -0
  31. data/spec/gemfiles/Gemfile.rails42 +7 -0
  32. data/spec/gemfiles/Gemfile.rails50 +10 -0
  33. data/spec/gemfiles/Gemfile.rails51 +10 -0
  34. data/spec/integration/active_record/active_record_spec.rb +38 -53
  35. data/spec/integration/mongoid/mongoid_spec.rb +37 -46
  36. data/spec/integration/shared/between_times.rb +82 -0
  37. data/spec/integration/shared/by_calendar_month.rb +55 -55
  38. data/spec/integration/shared/by_cweek.rb +54 -0
  39. data/spec/integration/shared/by_day.rb +96 -108
  40. data/spec/integration/shared/by_direction.rb +172 -153
  41. data/spec/integration/shared/by_fortnight.rb +48 -48
  42. data/spec/integration/shared/by_month.rb +50 -50
  43. data/spec/integration/shared/by_quarter.rb +49 -49
  44. data/spec/integration/shared/by_week.rb +54 -54
  45. data/spec/integration/shared/by_weekend.rb +49 -49
  46. data/spec/integration/shared/by_year.rb +48 -48
  47. data/spec/integration/shared/offset_parameter.rb +32 -31
  48. data/spec/integration/shared/order_parameter.rb +36 -0
  49. data/spec/integration/shared/relative.rb +174 -174
  50. data/spec/integration/shared/scope_parameter.rb +73 -72
  51. data/spec/spec_helper.rb +29 -29
  52. data/spec/unit/kernel_date_spec.rb +113 -60
  53. data/spec/unit/kernel_time_spec.rb +57 -57
  54. data/spec/unit/normalization_spec.rb +305 -255
  55. 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
- # Returns all records between a given start and finish time.
9
- #
10
- # Currently only supports Time objects.
11
- def between_times_query(start, finish, options={})
12
- start_field = by_star_start_field(options)
13
- end_field = by_star_end_field(options)
14
-
15
- scope = by_star_scope(options)
16
- scope = if options[:strict] || start_field == end_field
17
- scope.where("#{start_field} >= ? AND #{end_field} <= ?", start, finish)
18
- else
19
- scope.where("#{end_field} > ? AND #{start_field} < ?", start, finish)
20
- end
21
- scope = scope.order(options[:order]) if options[:order]
22
- scope
23
- end
24
-
25
- def between(*args)
26
- ActiveSupport::Deprecation.warn 'ByStar `between` method will be removed in v3.0.0. Please use `between_times`'
27
- between_times(*args)
28
- end
29
-
30
- protected
31
-
32
- def by_star_default_field
33
- "#{self.table_name}.created_at"
34
- end
35
-
36
- def before_query(time, options={})
37
- field = by_star_start_field(options)
38
- by_star_scope(options).where("#{field} <= ?", time)
39
- end
40
-
41
- def after_query(time, options={})
42
- field = by_star_start_field(options)
43
- by_star_scope(options).where("#{field} >= ?", time)
44
- end
45
-
46
- def oldest_query(options={})
47
- field = by_star_start_field(options)
48
- by_star_scope(options).reorder("#{field} ASC").first
49
- end
50
-
51
- def newest_query(options={})
52
- field = by_star_start_field(options)
53
- by_star_scope(options).reorder("#{field} DESC").first
54
- end
55
- end
56
-
57
- def previous(options={})
58
- field = self.class.by_star_start_field
59
- value = self.send(field.split(".").last)
60
- self.class.by_star_scope(options.merge(scope_args: self)).where("#{field} < ?", value).reorder("#{field} DESC").first
61
- end
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
- def between_times_query(start, finish, options={})
13
- start_field = by_star_start_field(options)
14
- end_field = by_star_end_field(options)
15
-
16
- scope = by_star_scope(options)
17
- scope = if options[:strict] || start_field == end_field
18
- scope.gte(start_field => start).lte(end_field => finish)
19
- else
20
- scope.gt(end_field => start).lt(start_field => finish)
21
- end
22
- scope = scope.order_by(field => options[:order]) if options[:order]
23
- scope
24
- end
25
-
26
- def by_star_end_field_with_mongoid(options = {})
27
- database_field_name by_star_end_field_without_mongoid(options)
28
- end
29
- alias_method_chain :by_star_end_field, :mongoid
30
-
31
- def by_star_start_field_with_mongoid(options = {})
32
- database_field_name by_star_start_field_without_mongoid(options)
33
- end
34
- alias_method_chain :by_star_start_field, :mongoid
35
-
36
- protected
37
-
38
- def by_star_default_field
39
- :created_at
40
- end
41
-
42
- def before_query(time, options={})
43
- field = by_star_start_field(options)
44
- by_star_scope(options).lte(field => time)
45
- end
46
-
47
- def after_query(time, options={})
48
- field = by_star_start_field(options)
49
- by_star_scope(options).gte(field => time)
50
- end
51
-
52
- def oldest_query(options={})
53
- field = by_star_start_field(options)
54
- by_star_scope(options).order_by(field => :asc).first
55
- end
56
-
57
- def newest_query(options={})
58
- field = by_star_start_field(options)
59
- by_star_scope(options).order_by(field => :desc).first
60
- end
61
- end
62
-
63
- def previous(options={})
64
- field = self.class.by_star_start_field
65
- self.class.by_star_scope(options.merge(scope_args: self)).lt(field => self.send(field)).desc(field).first
66
- end
67
-
68
- def next(options={})
69
- field = self.class.by_star_start_field
70
- self.class.by_star_scope(options.merge(scope_args: self)).gt(field => self.send(field)).asc(field).first
71
- end
72
- end
73
- end
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
@@ -1,3 +1,3 @@
1
- module ByStar
2
- VERSION = '2.2.1'
3
- end
1
+ module ByStar
2
+ VERSION = '3.0.0'
3
+ end
@@ -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
- end
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, :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
+ 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
- end
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