blind_date 0.0.1 → 0.0.2
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.
- data/VERSION +1 -1
- data/blind_date.gemspec +4 -4
- data/lib/blind_date/active_record/base.rb +46 -30
- data/lib/blind_date/active_record/connection_adapters/abstract_adapter.rb +44 -37
- data/lib/blind_date/active_record/connection_adapters/mysql_adapter.rb +12 -3
- data/lib/blind_date/active_record/connection_adapters/postgresql_adapter.rb +19 -10
- data/lib/blind_date/active_record/connection_adapters/sqlite_adapter.rb +19 -10
- data/lib/blind_date.rb +2 -2
- metadata +37 -13
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
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 = "0.0.2"
|
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{
|
12
|
+
s.date = %q{2010-06-14}
|
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 = [
|
@@ -38,7 +38,7 @@ Gem::Specification.new do |s|
|
|
38
38
|
s.homepage = %q{http://github.com/aepstein/blind_date}
|
39
39
|
s.rdoc_options = ["--charset=UTF-8"]
|
40
40
|
s.require_paths = ["lib"]
|
41
|
-
s.rubygems_version = %q{1.3.
|
41
|
+
s.rubygems_version = %q{1.3.7}
|
42
42
|
s.summary = %q{DBMS-indepedent methods to query dates in ActiveRecord}
|
43
43
|
s.test_files = [
|
44
44
|
"spec/blind_date_spec.rb",
|
@@ -49,7 +49,7 @@ Gem::Specification.new do |s|
|
|
49
49
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
50
50
|
s.specification_version = 3
|
51
51
|
|
52
|
-
if Gem::Version.new(Gem::
|
52
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
53
53
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
54
54
|
s.add_runtime_dependency(%q<activerecord>, [">= 2.3.4"])
|
55
55
|
else
|
@@ -1,42 +1,58 @@
|
|
1
1
|
module BlindDate
|
2
2
|
module ActiveRecord
|
3
3
|
module Base
|
4
|
+
module ClassMethods
|
5
|
+
# Generates an sql fragement representing the sum of a date and a duration
|
6
|
+
# == Usage
|
7
|
+
#
|
8
|
+
# Model.date_add DateTime.now, 10.days
|
9
|
+
# => sqlite: DATETIME( '2009-11-25 12:01:01', '+10 DAY' )
|
10
|
+
# => mysql: ('2009-11-25 12:01:01' + 10 DAY)
|
11
|
+
# => pgsql: (TIMESTAMP '2009-11-25 12:01:01' + '10 DAY')
|
12
|
+
# Model.date_add 'models.starts_at', 10.days
|
13
|
+
# => sqlite: DATETIME( models.starts_at, '+10 DAY' )
|
14
|
+
# Model.date_add :starts_at, :duration, :days
|
15
|
+
# => sqlite: DATETIME( "models"."starts_at", '+' || "models"."duration" || ' DAY' )
|
16
|
+
# Model.date_add :starts_at, :duration, :days, true
|
17
|
+
# => sqlite: DATETIME( "models"."starts_at", '-' || "models"."duration" || ' DAY' )
|
18
|
+
#
|
19
|
+
# == Options
|
20
|
+
# * +date+ - Date subject to calculation, can be date, time, datetime, symbolized column, or string sql fragment
|
21
|
+
# * +interval+ - Duration to be added/subtracted, can be duration, number, symbolized column, or string sql fragment
|
22
|
+
# * +unit+ - Unit of time for duration, defaults to :seconds, and is ignored if using duration for interval
|
23
|
+
# * +diff+ - If true, will subtract duration from date, otherwise will add (default is false)
|
24
|
+
def date_add( date, interval, unit = 'SECOND', diff = false)
|
25
|
+
if date.is_a? Symbol
|
26
|
+
date = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(date.to_s)}"
|
27
|
+
elsif date.acts_like?(:time) || date.acts_like?(:date)
|
28
|
+
date = connection.quote date
|
29
|
+
end
|
30
|
+
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
|
32
|
+
end
|
4
33
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# => sqlite: DATETIME( '2009-11-25 12:01:01', '+10 DAY' )
|
10
|
-
# => mysql: ('2009-11-25 12:01:01' + 10 DAY)
|
11
|
-
# => pgsql: (TIMESTAMP '2009-11-25 12:01:01' + '10 DAY')
|
12
|
-
# Model.date_add 'models.starts_at', 10.days
|
13
|
-
# => sqlite: DATETIME( models.starts_at, '+10 DAY' )
|
14
|
-
# Model.date_add :starts_at, :duration, :days
|
15
|
-
# => sqlite: DATETIME( "models"."starts_at", '+' || "models"."duration" || ' DAY' )
|
16
|
-
# Model.date_add :starts_at, :duration, :days, true
|
17
|
-
# => sqlite: DATETIME( "models"."starts_at", '-' || "models"."duration" || ' DAY' )
|
18
|
-
#
|
19
|
-
# == Options
|
20
|
-
# * +date+ - Date subject to calculation, can be date, time, datetime, symbolized column, or string sql fragment
|
21
|
-
# * +interval+ - Duration to be added/subtracted, can be duration, number, symbolized column, or string sql fragment
|
22
|
-
# * +unit+ - Unit of time for duration, defaults to :seconds, and is ignored if using duration for interval
|
23
|
-
# * +diff+ - If true, will subtract duration from date, otherwise will add (default is false)
|
24
|
-
def date_add( date, interval, unit = 'SECOND', diff = false)
|
25
|
-
if date.is_a? Symbol
|
26
|
-
date = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(date.to_s)}"
|
27
|
-
elsif date.acts_like?(:time) || date.acts_like?(:date)
|
28
|
-
date = connection.quote date
|
34
|
+
# Generates a SQL fragment representing subtraction of a duration from a date
|
35
|
+
# Similar to date_add( date, interval, unit, +true+ )
|
36
|
+
def date_sub( date, interval, unit = 'SECOND' )
|
37
|
+
date_add date, interval, unit, true
|
29
38
|
end
|
30
|
-
|
31
|
-
connection.class.date_add date, interval, unit, diff
|
39
|
+
|
32
40
|
end
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
module InstanceMethods
|
43
|
+
def date_add( date, interval, unit = 'SECOND', diff = false)
|
44
|
+
self.class.date_add( date, interval, unit, diff )
|
45
|
+
end
|
46
|
+
def date_sub( date, interval, unit = 'SECOND' )
|
47
|
+
self.class.date_sub( date, interval, unit )
|
48
|
+
end
|
38
49
|
end
|
39
50
|
|
51
|
+
def self.included(receiver)
|
52
|
+
receiver.extend ClassMethods
|
53
|
+
receiver.send :include, InstanceMethods
|
54
|
+
|
55
|
+
end
|
40
56
|
end
|
41
57
|
end
|
42
58
|
end
|
@@ -1,56 +1,63 @@
|
|
1
1
|
module BlindDate
|
2
2
|
module ActiveRecord
|
3
3
|
module ConnectionAdapters
|
4
|
-
|
5
|
-
# Includes extended behaviors
|
6
|
-
# Each DBMS-specific module must implement the private methods or raise NotImplemented
|
7
|
-
# for each private method
|
8
4
|
module AbstractAdapter
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
module ClassMethods
|
6
|
+
|
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 )
|
9
|
+
case interval
|
10
|
+
when ActiveSupport::Duration
|
11
|
+
interval.parts.inject( date ) do |memo, span|
|
12
|
+
date_add_sql_without_operator memo, span.last, span.first.to_s.singularize.upcase, diff
|
13
|
+
end
|
14
|
+
when String
|
15
|
+
date_add_sql date, interval, unit.to_s.singularize.upcase, ( diff ? '-' : '+' )
|
16
|
+
when Numeric
|
17
|
+
date_add_sql_without_operator date, interval, unit.to_s.singularize.upcase, diff
|
18
|
+
else
|
19
|
+
raise ArgumentError
|
16
20
|
end
|
17
|
-
when String
|
18
|
-
date_add_sql date, interval, unit.to_s.singularize.upcase, ( diff ? '-' : '+' )
|
19
|
-
when Numeric
|
20
|
-
date_add_sql_without_operator date, interval, unit.to_s.singularize.upcase, diff
|
21
|
-
else
|
22
|
-
raise ArgumentError
|
23
21
|
end
|
24
|
-
end
|
25
22
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
# Returns name of adapter suitable for loading related classes
|
24
|
+
# Should have same output as instance method of same name
|
25
|
+
# TODO: Kludgy: maybe upstream could provide a class method?
|
26
|
+
def adapter_name
|
27
|
+
to_s.underscore[ /\/([^\/]+)_adapter$/, 1 ].gsub( '_', '' )
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
32
31
|
|
33
|
-
|
32
|
+
# Adds appropriate operator before calling adapter-specific method
|
33
|
+
def date_add_sql_without_operator( sql, interval, unit, diff )
|
34
|
+
if diff
|
35
|
+
date_add_sql sql, interval.abs, unit, ( interval < 0 ? '+' : '-' )
|
36
|
+
else
|
37
|
+
date_add_sql sql, interval.abs, unit, ( interval < 0 ? '-' : '+' )
|
38
|
+
end
|
39
|
+
end
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
date_add_sql sql, interval
|
39
|
-
else
|
40
|
-
date_add_sql sql, interval.abs, unit, ( interval < 0 ? '-' : '+' )
|
41
|
+
# Will attempt to load the correct behavior if this is not already provided
|
42
|
+
def date_add_sql( sql, interval, unit, operator )
|
43
|
+
require "blind_date/active_record/connection_adapters/#{adapter_name}_adapter"
|
44
|
+
date_add_sql( sql, interval, unit, operator )
|
41
45
|
end
|
46
|
+
|
42
47
|
end
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
module InstanceMethods
|
50
|
+
def date_add_sql( sql, interval, unit, operator )
|
51
|
+
self.class.date_add_sql( sql, interval, unit, operator )
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
55
|
+
def self.included(receiver)
|
56
|
+
receiver.extend ClassMethods
|
57
|
+
receiver.send :include, InstanceMethods
|
58
|
+
end
|
50
59
|
end
|
51
60
|
end
|
52
61
|
end
|
53
62
|
end
|
54
63
|
|
55
|
-
ActiveRecord::ConnectionAdapters::AbstractAdapter.extend BlindDate::ActiveRecord::ConnectionAdapters::AbstractAdapter
|
56
|
-
|
@@ -2,15 +2,24 @@ module BlindDate
|
|
2
2
|
module ActiveRecord
|
3
3
|
module ConnectionAdapters
|
4
4
|
module MysqlAdapter
|
5
|
+
module ClassMethods
|
6
|
+
def date_add_sql( sql, interval, unit, operator )
|
7
|
+
"( #{sql} #{operator} INTERVAL #{interval} #{unit} )"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
5
12
|
|
6
|
-
def date_add_sql( sql, interval, unit, operator )
|
7
|
-
"( #{sql} #{operator} INTERVAL #{interval} #{unit} )"
|
8
13
|
end
|
9
14
|
|
15
|
+
def self.included(receiver)
|
16
|
+
receiver.extend ClassMethods
|
17
|
+
receiver.send :include, InstanceMethods
|
18
|
+
end
|
10
19
|
end
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
14
23
|
|
15
|
-
ActiveRecord::ConnectionAdapters::MysqlAdapter.
|
24
|
+
ActiveRecord::ConnectionAdapters::MysqlAdapter.send :include, BlindDate::ActiveRecord::ConnectionAdapters::MysqlAdapter
|
16
25
|
|
@@ -2,22 +2,31 @@ module BlindDate
|
|
2
2
|
module ActiveRecord
|
3
3
|
module ConnectionAdapters
|
4
4
|
module PostgresqlAdapter
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
module ClassMethods
|
6
|
+
def date_add_sql( sql, interval, unit, operator )
|
7
|
+
case interval
|
8
|
+
when Numeric
|
9
|
+
"( #{sql} #{operator} '#{interval} #{unit}' )"
|
10
|
+
when String
|
11
|
+
"( #{sql} #{operator} #{interval} || ' #{unit}')"
|
12
|
+
else
|
13
|
+
raise ArgumentError
|
14
|
+
end
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
module InstanceMethods
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.included(receiver)
|
23
|
+
receiver.extend ClassMethods
|
24
|
+
receiver.send :include, InstanceMethods
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
20
29
|
end
|
21
30
|
|
22
|
-
ActiveRecord::ConnectionAdapters::
|
31
|
+
ActiveRecord::ConnectionAdapters::PostgresqlAdapter.send :include, BlindDate::ActiveRecord::ConnectionAdapters::PostgresqlAdapter
|
23
32
|
|
@@ -2,22 +2,31 @@ module BlindDate
|
|
2
2
|
module ActiveRecord
|
3
3
|
module ConnectionAdapters
|
4
4
|
module SQLiteAdapter
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
module ClassMethods
|
6
|
+
def date_add_sql( sql, interval, unit, operator )
|
7
|
+
case interval
|
8
|
+
when Numeric
|
9
|
+
"DATETIME( #{sql}, '#{operator}#{interval} #{unit}' )"
|
10
|
+
when String
|
11
|
+
"DATETIME( #{sql}, '#{operator}' || #{interval} || ' #{unit}' )"
|
12
|
+
else
|
13
|
+
raise ArgumentError
|
14
|
+
end
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
module InstanceMethods
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.included(receiver)
|
23
|
+
receiver.extend ClassMethods
|
24
|
+
receiver.send :include, InstanceMethods
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
20
29
|
end
|
21
30
|
|
22
|
-
ActiveRecord::ConnectionAdapters::SQLiteAdapter.
|
31
|
+
ActiveRecord::ConnectionAdapters::SQLiteAdapter.send :include, BlindDate::ActiveRecord::ConnectionAdapters::SQLiteAdapter
|
23
32
|
|
data/lib/blind_date.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'blind_date/active_record/base'
|
2
2
|
require 'blind_date/active_record/connection_adapters/abstract_adapter'
|
3
3
|
|
4
|
-
ActiveRecord::Base.
|
5
|
-
ActiveRecord::ConnectionAdapters::AbstractAdapter.
|
4
|
+
ActiveRecord::Base.send :include, BlindDate::ActiveRecord::Base
|
5
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.send :include, BlindDate::ActiveRecord::ConnectionAdapters::AbstractAdapter
|
6
6
|
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blind_date
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Ari Epstein
|
@@ -9,29 +15,41 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-06-14 00:00:00 -04:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: rspec
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 2
|
33
|
+
- 9
|
23
34
|
version: 1.2.9
|
24
|
-
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: activerecord
|
27
|
-
|
28
|
-
|
29
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
30
42
|
requirements:
|
31
43
|
- - ">="
|
32
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 11
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 3
|
49
|
+
- 4
|
33
50
|
version: 2.3.4
|
34
|
-
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
35
53
|
description: Allows you to utilize date calculation functionality of DBMS with a uniform API
|
36
54
|
email: aepstein607@gmail.com
|
37
55
|
executables: []
|
@@ -69,21 +87,27 @@ rdoc_options:
|
|
69
87
|
require_paths:
|
70
88
|
- lib
|
71
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
72
91
|
requirements:
|
73
92
|
- - ">="
|
74
93
|
- !ruby/object:Gem::Version
|
94
|
+
hash: 3
|
95
|
+
segments:
|
96
|
+
- 0
|
75
97
|
version: "0"
|
76
|
-
version:
|
77
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
78
100
|
requirements:
|
79
101
|
- - ">="
|
80
102
|
- !ruby/object:Gem::Version
|
103
|
+
hash: 3
|
104
|
+
segments:
|
105
|
+
- 0
|
81
106
|
version: "0"
|
82
|
-
version:
|
83
107
|
requirements: []
|
84
108
|
|
85
109
|
rubyforge_project:
|
86
|
-
rubygems_version: 1.3.
|
110
|
+
rubygems_version: 1.3.7
|
87
111
|
signing_key:
|
88
112
|
specification_version: 3
|
89
113
|
summary: DBMS-indepedent methods to query dates in ActiveRecord
|