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.
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