blind_date 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/blind_date.gemspec +2 -2
- data/lib/blind_date/active_record/base.rb +47 -8
- data/lib/blind_date/active_record/connection_adapters/abstract_adapter.rb +11 -11
- data/lib/blind_date/active_record/connection_adapters/mysql_adapter.rb +1 -1
- data/lib/blind_date/active_record/connection_adapters/postgresql_adapter.rb +1 -1
- data/lib/blind_date/active_record/connection_adapters/sqlite_adapter.rb +12 -7
- data/spec/blind_date_spec.rb +13 -13
- metadata +3 -8
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
1.0.0
|
data/blind_date.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{blind_date}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "1.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ari Epstein"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-12}
|
13
13
|
s.description = %q{Allows you to utilize date calculation functionality of DBMS with a uniform API}
|
14
14
|
s.email = %q{aepstein607@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -2,6 +2,32 @@ module BlindDate
|
|
2
2
|
module ActiveRecord
|
3
3
|
module Base
|
4
4
|
module ClassMethods
|
5
|
+
def date_add( date, interval, unit = 'DAY' )
|
6
|
+
blind_date_add :date, date, interval, unit
|
7
|
+
end
|
8
|
+
|
9
|
+
def date_sub( date, interval, unit = 'DAY' )
|
10
|
+
blind_date_sub :date, date, interval, unit
|
11
|
+
end
|
12
|
+
|
13
|
+
def datetime_add( date, interval, unit = 'SECOND' )
|
14
|
+
blind_date_add :datetime, date, interval, unit
|
15
|
+
end
|
16
|
+
|
17
|
+
def datetime_sub( date, interval, unit = 'SECOND' )
|
18
|
+
blind_date_sub :datetime, date, interval, unit
|
19
|
+
end
|
20
|
+
|
21
|
+
def time_add( date, interval, unit = 'SECOND' )
|
22
|
+
blind_date_add :time, date, interval, unit
|
23
|
+
end
|
24
|
+
|
25
|
+
def time_sub( date, interval, unit = 'SECOND' )
|
26
|
+
blind_date_sub :time, date, interval, unit
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
5
31
|
# Generates an sql fragement representing the sum of a date and a duration
|
6
32
|
# == Usage
|
7
33
|
#
|
@@ -17,35 +43,48 @@ module BlindDate
|
|
17
43
|
# => sqlite: DATETIME( "models"."starts_at", '-' || "models"."duration" || ' DAY' )
|
18
44
|
#
|
19
45
|
# == Options
|
46
|
+
# * +style+ = - Style of time calculation (applicable only in sqlite)
|
20
47
|
# * +date+ - Date subject to calculation, can be date, time, datetime, symbolized column, or string sql fragment
|
21
48
|
# * +interval+ - Duration to be added/subtracted, can be duration, number, symbolized column, or string sql fragment
|
22
49
|
# * +unit+ - Unit of time for duration, defaults to :seconds, and is ignored if using duration for interval
|
23
50
|
# * +diff+ - If true, will subtract duration from date, otherwise will add (default is false)
|
24
|
-
def
|
51
|
+
def blind_date_add( style, date, interval, unit = 'SECOND', diff = false)
|
25
52
|
if date.is_a? Symbol
|
26
53
|
date = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(date.to_s)}"
|
27
54
|
elsif date.acts_like?(:time) || date.acts_like?(:date)
|
28
55
|
date = connection.quote date
|
29
56
|
end
|
30
57
|
interval = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(interval.to_s)}" if interval.is_a? Symbol
|
31
|
-
connection.class.date_add date, interval, unit, diff
|
58
|
+
connection.class.date_add style, date, interval, unit, diff
|
32
59
|
end
|
33
60
|
|
34
61
|
# Generates a SQL fragment representing subtraction of a duration from a date
|
35
|
-
# Similar to date_add( date, interval, unit, +true+ )
|
36
|
-
def
|
37
|
-
|
62
|
+
# Similar to date_add( style, date, interval, unit, +true+ )
|
63
|
+
def blind_date_sub( style, date, interval, unit = 'SECOND' )
|
64
|
+
blind_date_add style, date, interval, unit, true
|
38
65
|
end
|
39
66
|
|
40
67
|
end
|
41
68
|
|
42
69
|
module InstanceMethods
|
43
|
-
def date_add( date, interval, unit = '
|
44
|
-
self.class.date_add( date, interval, unit
|
70
|
+
def date_add( date, interval, unit = 'DAY')
|
71
|
+
self.class.date_add( date, interval, unit )
|
45
72
|
end
|
46
|
-
def date_sub( date, interval, unit = '
|
73
|
+
def date_sub( date, interval, unit = 'DAY' )
|
47
74
|
self.class.date_sub( date, interval, unit )
|
48
75
|
end
|
76
|
+
def datetime_add( date, interval, unit = 'SECOND' )
|
77
|
+
self.class.datetime_add( date, interval, unit )
|
78
|
+
end
|
79
|
+
def datetime_sub( date, interval, unit = 'SECOND' )
|
80
|
+
self.class.datetime_sub( date, interval, unit )
|
81
|
+
end
|
82
|
+
def time_add( date, interval, unit = 'SECOND' )
|
83
|
+
self.class.time_add( date, interval, unit )
|
84
|
+
end
|
85
|
+
def time_sub( date, interval, unit = 'SECOND' )
|
86
|
+
self.class.time_sub( date, interval, unit )
|
87
|
+
end
|
49
88
|
end
|
50
89
|
|
51
90
|
def self.included(receiver)
|
@@ -5,16 +5,16 @@ module BlindDate
|
|
5
5
|
module ClassMethods
|
6
6
|
|
7
7
|
# Performs arithmetic on string is an SQL-escaped date/time/datetime or returns a date/time/datetime
|
8
|
-
def date_add(date, interval, unit = 'SECOND', diff = false )
|
8
|
+
def date_add( style, date, interval, unit = 'SECOND', diff = false )
|
9
9
|
case interval
|
10
10
|
when ActiveSupport::Duration
|
11
11
|
interval.parts.inject( date ) do |memo, span|
|
12
|
-
date_add_sql_without_operator memo, span.last, span.first.to_s.singularize.upcase, diff
|
12
|
+
date_add_sql_without_operator style, memo, span.last, span.first.to_s.singularize.upcase, diff
|
13
13
|
end
|
14
14
|
when String
|
15
|
-
date_add_sql date, interval, unit.to_s.singularize.upcase, ( diff ? '-' : '+' )
|
15
|
+
date_add_sql style, date, interval, unit.to_s.singularize.upcase, ( diff ? '-' : '+' )
|
16
16
|
when Numeric
|
17
|
-
date_add_sql_without_operator date, interval, unit.to_s.singularize.upcase, diff
|
17
|
+
date_add_sql_without_operator style, date, interval, unit.to_s.singularize.upcase, diff
|
18
18
|
else
|
19
19
|
raise ArgumentError
|
20
20
|
end
|
@@ -30,25 +30,25 @@ module BlindDate
|
|
30
30
|
private
|
31
31
|
|
32
32
|
# Adds appropriate operator before calling adapter-specific method
|
33
|
-
def date_add_sql_without_operator( sql, interval, unit, diff )
|
33
|
+
def date_add_sql_without_operator( style, sql, interval, unit, diff )
|
34
34
|
if diff
|
35
|
-
date_add_sql sql, interval.abs, unit, ( interval < 0 ? '+' : '-' )
|
35
|
+
date_add_sql style, sql, interval.abs, unit, ( interval < 0 ? '+' : '-' )
|
36
36
|
else
|
37
|
-
date_add_sql sql, interval.abs, unit, ( interval < 0 ? '-' : '+' )
|
37
|
+
date_add_sql style, sql, interval.abs, unit, ( interval < 0 ? '-' : '+' )
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
# Will attempt to load the correct behavior if this is not already provided
|
42
|
-
def date_add_sql( sql, interval, unit, operator )
|
42
|
+
def date_add_sql( style, sql, interval, unit, operator )
|
43
43
|
require "blind_date/active_record/connection_adapters/#{adapter_name}_adapter"
|
44
|
-
date_add_sql( sql, interval, unit, operator )
|
44
|
+
date_add_sql( style, sql, interval, unit, operator )
|
45
45
|
end
|
46
46
|
|
47
47
|
end
|
48
48
|
|
49
49
|
module InstanceMethods
|
50
|
-
def date_add_sql( sql, interval, unit, operator )
|
51
|
-
self.class.date_add_sql( sql, interval, unit, operator )
|
50
|
+
def date_add_sql( style, sql, interval, unit, operator )
|
51
|
+
self.class.date_add_sql( style, sql, interval, unit, operator )
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -3,7 +3,7 @@ module BlindDate
|
|
3
3
|
module ConnectionAdapters
|
4
4
|
module PostgresqlAdapter
|
5
5
|
module ClassMethods
|
6
|
-
def date_add_sql( sql, interval, unit, operator )
|
6
|
+
def date_add_sql( style, sql, interval, unit, operator )
|
7
7
|
case interval
|
8
8
|
when Numeric
|
9
9
|
"( #{sql} #{operator} '#{interval} #{unit}' )"
|
@@ -3,14 +3,19 @@ module BlindDate
|
|
3
3
|
module ConnectionAdapters
|
4
4
|
module SQLiteAdapter
|
5
5
|
module ClassMethods
|
6
|
-
def date_add_sql( sql, interval, unit, operator )
|
6
|
+
def date_add_sql( style, sql, interval, unit, operator )
|
7
|
+
date_function = case style
|
8
|
+
when :date then 'DATE'
|
9
|
+
when :datetime then 'DATETIME'
|
10
|
+
when :time then 'TIME'
|
11
|
+
end
|
7
12
|
case interval
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
when Numeric
|
14
|
+
"#{date_function}( #{sql}, '#{operator}#{interval} #{unit}' )"
|
15
|
+
when String
|
16
|
+
"#{date_function}( #{sql}, '#{operator}' || #{interval} || ' #{unit}' )"
|
17
|
+
else
|
18
|
+
raise ArgumentError
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
data/spec/blind_date_spec.rb
CHANGED
@@ -6,65 +6,65 @@ describe "BlindDate" do
|
|
6
6
|
@future = Activity.create( :starts_at => @activity.starts_at + 60.seconds, :duration => 60 )
|
7
7
|
end
|
8
8
|
|
9
|
-
it "should produce valid
|
10
|
-
matches = matches_for Activity.
|
9
|
+
it "should produce valid datetime_add output" do
|
10
|
+
matches = matches_for Activity.datetime_add( @activity.starts_at, 60.seconds )
|
11
11
|
matches.size.should eql 1
|
12
12
|
matches.should include @future
|
13
13
|
end
|
14
14
|
|
15
|
-
it "should produce valid
|
15
|
+
it "should produce valid datetime_add output with plain sql string" do
|
16
16
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote(@future.starts_at)} = " +
|
17
|
-
Activity.
|
17
|
+
Activity.datetime_add( 'activities.starts_at', 60.seconds ) ] )
|
18
18
|
matches.size.should eql 1
|
19
19
|
matches.should include @activity
|
20
20
|
end
|
21
21
|
|
22
|
-
it "should produce valid
|
22
|
+
it "should produce valid datetime_add output with multipart date" do
|
23
23
|
other_activity = Activity.create( :starts_at => @activity.starts_at + 2.months + 10.seconds )
|
24
24
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote(other_activity.starts_at)} = " +
|
25
|
-
Activity.
|
25
|
+
Activity.datetime_add( :starts_at, 2.months + 10.seconds ) ])
|
26
26
|
matches.size.should eql 1
|
27
27
|
matches.should include @activity
|
28
28
|
end
|
29
29
|
|
30
|
-
it "should produce valid
|
30
|
+
it "should produce valid datetime_add output with a symbol string" do
|
31
31
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote(@future.starts_at)} = " +
|
32
|
-
Activity.
|
32
|
+
Activity.datetime_add( :starts_at, 60.seconds ) ] )
|
33
33
|
matches.size.should eql 1
|
34
34
|
matches.should include @activity
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should default to seconds with an integer interval" do
|
38
38
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote(@future.starts_at)} = " +
|
39
|
-
Activity.
|
39
|
+
Activity.datetime_add( :starts_at, 60 ) ] )
|
40
40
|
matches.size.should eql 1
|
41
41
|
matches.should include @activity
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should accept sql fragment, unit, operator for interval" do
|
45
45
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote(@activity.starts_at + @activity.duration.seconds)} = " +
|
46
|
-
Activity.
|
46
|
+
Activity.datetime_add( :starts_at, 'activities.duration' ) ] )
|
47
47
|
matches.size.should eql 1
|
48
48
|
matches.should include @activity
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should accept a symbol for the interval" do
|
52
52
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote(@activity.starts_at + @activity.duration.seconds)} = " +
|
53
|
-
Activity.
|
53
|
+
Activity.datetime_add( :starts_at, :duration ) ] )
|
54
54
|
matches.size.should eql 1
|
55
55
|
matches.should include @activity
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should accept an alternative unit for a specified interval" do
|
59
59
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote(@activity.starts_at + @activity.duration.seconds)} = " +
|
60
|
-
Activity.
|
60
|
+
Activity.datetime_add( :starts_at, 1, :minutes ) ] )
|
61
61
|
matches.size.should eql 1
|
62
62
|
matches.should include @activity
|
63
63
|
end
|
64
64
|
|
65
65
|
it "should calculate a difference with the sub method" do
|
66
66
|
matches = Activity.find( :all, :conditions => [ "#{@activity.connection.quote @activity.starts_at} = " +
|
67
|
-
Activity.
|
67
|
+
Activity.datetime_sub( 'activities.starts_at', 1, :minutes ) ] )
|
68
68
|
matches.size.should eql 1
|
69
69
|
matches.should include @future
|
70
70
|
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blind_date
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 27
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
6
|
+
- 1
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.2
|
9
|
+
version: 1.0.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Ari Epstein
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-
|
17
|
+
date: 2010-11-12 00:00:00 -05:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -26,7 +25,6 @@ dependencies:
|
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 13
|
30
28
|
segments:
|
31
29
|
- 1
|
32
30
|
- 2
|
@@ -42,7 +40,6 @@ dependencies:
|
|
42
40
|
requirements:
|
43
41
|
- - ">="
|
44
42
|
- !ruby/object:Gem::Version
|
45
|
-
hash: 11
|
46
43
|
segments:
|
47
44
|
- 2
|
48
45
|
- 3
|
@@ -91,7 +88,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
88
|
requirements:
|
92
89
|
- - ">="
|
93
90
|
- !ruby/object:Gem::Version
|
94
|
-
hash: 3
|
95
91
|
segments:
|
96
92
|
- 0
|
97
93
|
version: "0"
|
@@ -100,7 +96,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
96
|
requirements:
|
101
97
|
- - ">="
|
102
98
|
- !ruby/object:Gem::Version
|
103
|
-
hash: 3
|
104
99
|
segments:
|
105
100
|
- 0
|
106
101
|
version: "0"
|