sequel 3.42.0 → 3.43.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +40 -0
- data/MIT-LICENSE +1 -1
- data/Rakefile +1 -1
- data/doc/opening_databases.rdoc +2 -2
- data/doc/prepared_statements.rdoc +7 -0
- data/doc/release_notes/3.43.0.txt +105 -0
- data/doc/schema_modification.rdoc +19 -0
- data/lib/sequel/adapters/do/mysql.rb +1 -1
- data/lib/sequel/adapters/jdbc.rb +13 -8
- data/lib/sequel/adapters/jdbc/hsqldb.rb +5 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +6 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -3
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +4 -2
- data/lib/sequel/adapters/shared/db2.rb +12 -0
- data/lib/sequel/adapters/shared/mssql.rb +9 -5
- data/lib/sequel/adapters/shared/postgres.rb +2 -0
- data/lib/sequel/adapters/swift/mysql.rb +1 -1
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database.rb +0 -2
- data/lib/sequel/database/query.rb +20 -5
- data/lib/sequel/database/schema_generator.rb +5 -0
- data/lib/sequel/database/schema_methods.rb +5 -0
- data/lib/sequel/dataset.rb +0 -2
- data/lib/sequel/dataset/actions.rb +25 -2
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/sql.rb +28 -6
- data/lib/sequel/extensions/core_refinements.rb +221 -0
- data/lib/sequel/extensions/date_arithmetic.rb +194 -0
- data/lib/sequel/extensions/meta_def.rb +30 -0
- data/lib/sequel/extensions/migration.rb +5 -0
- data/lib/sequel/extensions/null_dataset.rb +2 -0
- data/lib/sequel/extensions/pagination.rb +2 -0
- data/lib/sequel/extensions/pg_array.rb +12 -1
- data/lib/sequel/extensions/pg_array_ops.rb +10 -1
- data/lib/sequel/extensions/pg_hstore.rb +12 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +10 -1
- data/lib/sequel/extensions/pg_json.rb +18 -1
- data/lib/sequel/extensions/pg_range.rb +12 -1
- data/lib/sequel/extensions/pg_range_ops.rb +10 -1
- data/lib/sequel/extensions/pg_row.rb +18 -2
- data/lib/sequel/extensions/pg_row_ops.rb +10 -1
- data/lib/sequel/extensions/query.rb +2 -0
- data/lib/sequel/model/associations.rb +5 -13
- data/lib/sequel/model/base.rb +4 -6
- data/lib/sequel/plugins/boolean_readers.rb +4 -2
- data/lib/sequel/plugins/many_through_many.rb +23 -0
- data/lib/sequel/plugins/string_stripper.rb +53 -3
- data/lib/sequel/plugins/validation_class_methods.rb +5 -0
- data/lib/sequel/sql.rb +3 -3
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +19 -8
- data/spec/adapters/mssql_spec.rb +1 -2
- data/spec/adapters/mysql_spec.rb +2 -2
- data/spec/adapters/postgres_spec.rb +29 -3
- data/spec/core/dataset_spec.rb +107 -0
- data/spec/core/expression_filters_spec.rb +5 -0
- data/spec/core/schema_spec.rb +14 -3
- data/spec/core/spec_helper.rb +2 -0
- data/spec/extensions/core_refinements_spec.rb +551 -0
- data/spec/extensions/date_arithmetic_spec.rb +150 -0
- data/spec/extensions/force_encoding_spec.rb +1 -1
- data/spec/extensions/meta_def_spec.rb +21 -0
- data/spec/extensions/spec_helper.rb +5 -0
- data/spec/extensions/string_stripper_spec.rb +44 -2
- data/spec/integration/associations_test.rb +2 -2
- data/spec/integration/plugin_test.rb +90 -0
- data/spec/integration/schema_test.rb +1 -1
- data/spec/model/association_reflection_spec.rb +4 -4
- data/spec/model/associations_spec.rb +2 -2
- data/spec/model/base_spec.rb +2 -2
- data/spec/model/eager_loading_spec.rb +5 -5
- data/spec/model/hooks_spec.rb +4 -4
- data/spec/model/model_spec.rb +9 -9
- data/spec/model/record_spec.rb +15 -18
- metadata +12 -5
- data/lib/sequel/metaprogramming.rb +0 -13
@@ -0,0 +1,150 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
asd = begin
|
4
|
+
require 'active_support/duration'
|
5
|
+
true
|
6
|
+
rescue LoadError => e
|
7
|
+
skip_warn "date_arithmetic extension (partial): can't load active_support/duration (#{e.class}: #{e})"
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
Sequel.extension :date_arithmetic
|
12
|
+
|
13
|
+
describe "date_arithmetic extension" do
|
14
|
+
dbf = lambda do |db_type|
|
15
|
+
db = Sequel.connect("mock://#{db_type}")
|
16
|
+
db.extension :date_arithmetic
|
17
|
+
db
|
18
|
+
end
|
19
|
+
|
20
|
+
before do
|
21
|
+
@h0 = {:days=>0}
|
22
|
+
@h1 = {:days=>1, :years=>nil, :hours=>0}
|
23
|
+
@h2 = {:years=>1, :months=>1, :days=>1, :hours=>1, :minutes=>1, :seconds=>1}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have Sequel.date_add with an interval hash return an appropriate Sequel::SQL::DateAdd expression" do
|
27
|
+
da = Sequel.date_add(:a, :days=>1)
|
28
|
+
da.should be_a_kind_of(Sequel::SQL::DateAdd)
|
29
|
+
da.expr.should == :a
|
30
|
+
da.interval.should == {:days=>1}
|
31
|
+
Sequel.date_add(:a, :years=>1, :months=>2, :days=>3, :hours=>1, :minutes=>1, :seconds=>1).interval.should == {:years=>1, :months=>2, :days=>3, :hours=>1, :minutes=>1, :seconds=>1}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have Sequel.date_sub with an interval hash return an appropriate Sequel::SQL::DateAdd expression" do
|
35
|
+
da = Sequel.date_sub(:a, :days=>1)
|
36
|
+
da.should be_a_kind_of(Sequel::SQL::DateAdd)
|
37
|
+
da.expr.should == :a
|
38
|
+
da.interval.should == {:days=>-1}
|
39
|
+
Sequel.date_sub(:a, :years=>1, :months=>2, :days=>3, :hours=>1, :minutes=>1, :seconds=>1).interval.should == {:years=>-1, :months=>-2, :days=>-3, :hours=>-1, :minutes=>-1, :seconds=>-1}
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have Sequel.date_* with an interval hash handle nil values" do
|
43
|
+
Sequel.date_sub(:a, :days=>1, :hours=>nil).interval.should == {:days=>-1}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise an error if given string values in an interval hash" do
|
47
|
+
lambda{Sequel.date_add(:a, :days=>'1')}.should raise_error(Sequel::InvalidValue)
|
48
|
+
end
|
49
|
+
|
50
|
+
if asd
|
51
|
+
it "should have Sequel.date_add with an ActiveSupport::Duration return an appropriate Sequel::SQL::DateAdd expression" do
|
52
|
+
da = Sequel.date_add(:a, ActiveSupport::Duration.new(1, [[:days, 1]]))
|
53
|
+
da.should be_a_kind_of(Sequel::SQL::DateAdd)
|
54
|
+
da.expr.should == :a
|
55
|
+
da.interval.should == {:days=>1}
|
56
|
+
Sequel.date_add(:a, ActiveSupport::Duration.new(1, [[:years, 1], [:months, 1], [:days, 1], [:minutes, 61], [:seconds, 1]])).interval.should == {:years=>1, :months=>1, :days=>1, :minutes=>61, :seconds=>1}
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have Sequel.date_sub with an ActiveSupport::Duration return an appropriate Sequel::SQL::DateAdd expression" do
|
60
|
+
da = Sequel.date_sub(:a, ActiveSupport::Duration.new(1, [[:days, 1]]))
|
61
|
+
da.should be_a_kind_of(Sequel::SQL::DateAdd)
|
62
|
+
da.expr.should == :a
|
63
|
+
da.interval.should == {:days=>-1}
|
64
|
+
Sequel.date_sub(:a, ActiveSupport::Duration.new(1, [[:years, 1], [:months, 1], [:days, 1], [:minutes, 61], [:seconds, 1]])).interval.should == {:years=>-1, :months=>-1, :days=>-1, :minutes=>-61, :seconds=>-1}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should correctly literalize on Postgres" do
|
69
|
+
db = dbf.call(:postgres)
|
70
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(a AS timestamp)"
|
71
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "(CAST(a AS timestamp) + CAST('1 days ' AS interval))"
|
72
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "(CAST(a AS timestamp) + CAST('1 years 1 months 1 days 1 hours 1 minutes 1 seconds ' AS interval))"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should correctly literalize on SQLite" do
|
76
|
+
db = dbf.call(:sqlite)
|
77
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "datetime(a)"
|
78
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "datetime(a, '1 days')"
|
79
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "datetime(a, '1 years', '1 months', '1 days', '1 hours', '1 minutes', '1 seconds')"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should correctly literalize on MySQL" do
|
83
|
+
db = dbf.call(:mysql)
|
84
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(a AS DATETIME)"
|
85
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "DATE_ADD(a, INTERVAL 1 DAY)"
|
86
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(a, INTERVAL 1 YEAR), INTERVAL 1 MONTH), INTERVAL 1 DAY), INTERVAL 1 HOUR), INTERVAL 1 MINUTE), INTERVAL 1 SECOND)"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should correctly literalize on HSQLDB" do
|
90
|
+
db = Sequel.mock
|
91
|
+
def db.database_type; :hsqldb end
|
92
|
+
db.extension :date_arithmetic
|
93
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(CAST(a AS timestamp) AS timestamp)"
|
94
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "DATE_ADD(CAST(a AS timestamp), INTERVAL 1 DAY)"
|
95
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(CAST(a AS timestamp), INTERVAL 1 YEAR), INTERVAL 1 MONTH), INTERVAL 1 DAY), INTERVAL 1 HOUR), INTERVAL 1 MINUTE), INTERVAL 1 SECOND)"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should correctly literalize on MSSQL" do
|
99
|
+
db = dbf.call(:mssql)
|
100
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(a AS datetime)"
|
101
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "DATEADD(day, 1, a)"
|
102
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "DATEADD(second, 1, DATEADD(minute, 1, DATEADD(hour, 1, DATEADD(day, 1, DATEADD(month, 1, DATEADD(year, 1, a))))))"
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should correctly literalize on H2" do
|
106
|
+
db = Sequel.mock
|
107
|
+
def db.database_type; :h2 end
|
108
|
+
db.extension :date_arithmetic
|
109
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(a AS timestamp)"
|
110
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "DATEADD('day', 1, a)"
|
111
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "DATEADD('second', 1, DATEADD('minute', 1, DATEADD('hour', 1, DATEADD('day', 1, DATEADD('month', 1, DATEADD('year', 1, a))))))"
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should correctly literalize on access" do
|
115
|
+
db = dbf.call(:access)
|
116
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CDate(a)"
|
117
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "DATEADD('d', 1, a)"
|
118
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "DATEADD('s', 1, DATEADD('n', 1, DATEADD('h', 1, DATEADD('d', 1, DATEADD('m', 1, DATEADD('yyyy', 1, a))))))"
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should correctly literalize on Derby" do
|
122
|
+
db = Sequel.mock
|
123
|
+
def db.database_type; :derby end
|
124
|
+
db.extension :date_arithmetic
|
125
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(a AS timestamp)"
|
126
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "{fn timestampadd(SQL_TSI_DAY, 1, timestamp(a))}"
|
127
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "{fn timestampadd(SQL_TSI_SECOND, 1, timestamp({fn timestampadd(SQL_TSI_MINUTE, 1, timestamp({fn timestampadd(SQL_TSI_HOUR, 1, timestamp({fn timestampadd(SQL_TSI_DAY, 1, timestamp({fn timestampadd(SQL_TSI_MONTH, 1, timestamp({fn timestampadd(SQL_TSI_YEAR, 1, timestamp(a))}))}))}))}))}))}"
|
128
|
+
db.literal(Sequel.date_add(Date.civil(2012, 11, 12), @h1)).should == "{fn timestampadd(SQL_TSI_DAY, 1, timestamp((CAST('2012-11-12' AS varchar(255)) || ' 00:00:00')))}"
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should correctly literalize on Oracle" do
|
132
|
+
db = dbf.call(:oracle)
|
133
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(a AS timestamp)"
|
134
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "(a + INTERVAL '1' DAY)"
|
135
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "(a + INTERVAL '1' YEAR + INTERVAL '1' MONTH + INTERVAL '1' DAY + INTERVAL '1' HOUR + INTERVAL '1' MINUTE + INTERVAL '1' SECOND)"
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should correctly literalize on DB2" do
|
139
|
+
db = dbf.call(:db2)
|
140
|
+
db.literal(Sequel.date_add(:a, @h0)).should == "CAST(a AS timestamp)"
|
141
|
+
db.literal(Sequel.date_add(:a, @h1)).should == "(CAST(a AS timestamp) + 1 days)"
|
142
|
+
db.literal(Sequel.date_add(:a, @h2)).should == "(CAST(a AS timestamp) + 1 years + 1 months + 1 days + 1 hours + 1 minutes + 1 seconds)"
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should raise error if literalizing on an unsupported database" do
|
146
|
+
db = Sequel.mock
|
147
|
+
db.extension :date_arithmetic
|
148
|
+
lambda{db.literal(Sequel.date_add(:a, @h0))}.should raise_error(Sequel::NotImplemented)
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
describe "Sequel::Metaprogramming" do
|
4
|
+
specify "should add meta_def method to Database, Dataset, and Model classes and instances" do
|
5
|
+
Sequel::Database.meta_def(:foo){1}
|
6
|
+
Sequel::Database.foo.should == 1
|
7
|
+
Sequel::Dataset.meta_def(:foo){2}
|
8
|
+
Sequel::Dataset.foo.should == 2
|
9
|
+
Sequel::Model.meta_def(:foo){3}
|
10
|
+
Sequel::Model.foo.should == 3
|
11
|
+
o = Sequel::Database.new
|
12
|
+
o.meta_def(:foo){4}
|
13
|
+
o.foo.should == 4
|
14
|
+
o = o[:a]
|
15
|
+
o.meta_def(:foo){5}
|
16
|
+
o.foo.should == 5
|
17
|
+
o = Sequel::Model.new
|
18
|
+
o.meta_def(:foo){6}
|
19
|
+
o.foo.should == 6
|
20
|
+
end
|
21
|
+
end
|
@@ -22,6 +22,11 @@ rescue LoadError
|
|
22
22
|
nil
|
23
23
|
end
|
24
24
|
|
25
|
+
Sequel.extension :meta_def
|
26
|
+
|
27
|
+
# Load core_refinements extension first, so pg_* extensions add their own refinements
|
28
|
+
Sequel.extension :core_refinements if RUBY_VERSION >= '2.0.0'
|
29
|
+
|
25
30
|
# Load most extensions by default, so that any conflicts are easily detectable.
|
26
31
|
Sequel.extension(*%w'string_date_time inflector pagination query pretty_table blank migration schema_dumper looser_typecasting sql_expr thread_local_timezones to_dot columns_introspection server_block arbitrary_servers pg_auto_parameterize pg_statement_cache pg_array pg_array_ops pg_hstore pg_hstore_ops pg_range pg_range_ops pg_json pg_inet pg_row pg_row_ops schema_caching null_dataset select_remove query_literals eval_inspect')
|
27
32
|
|
@@ -3,9 +3,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
3
3
|
describe "Sequel::Plugins::StringStripper" do
|
4
4
|
before do
|
5
5
|
@db = Sequel::Database.new
|
6
|
-
@c = Class.new(Sequel::Model(@db))
|
6
|
+
@c = Class.new(Sequel::Model(@db[:test]))
|
7
|
+
@c.columns :name, :b
|
8
|
+
@c.db_schema[:b][:type] = :blob
|
7
9
|
@c.plugin :string_stripper
|
8
|
-
@c.columns :name
|
9
10
|
@o = @c.new
|
10
11
|
end
|
11
12
|
|
@@ -20,4 +21,45 @@ describe "Sequel::Plugins::StringStripper" do
|
|
20
21
|
@o.name = Date.today
|
21
22
|
@o.name.should == Date.today
|
22
23
|
end
|
24
|
+
|
25
|
+
it "should not strip strings for blob arguments" do
|
26
|
+
v = Sequel.blob(' name ')
|
27
|
+
@o.name = v
|
28
|
+
@o.name.should equal(v)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not strip strings for blob columns" do
|
32
|
+
@o.b = ' name '
|
33
|
+
@o.b.should be_a_kind_of(Sequel::SQL::Blob)
|
34
|
+
@o.b.should == Sequel.blob(' name ')
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should allow skipping of columns using Model.skip_string_stripping" do
|
38
|
+
@c.skip_string_stripping :name
|
39
|
+
v = ' name '
|
40
|
+
@o.name = v
|
41
|
+
@o.name.should equal(v)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should work correctly in subclasses" do
|
45
|
+
o = Class.new(@c).new
|
46
|
+
o.name = ' name '
|
47
|
+
o.name.should == 'name'
|
48
|
+
o.b = ' name '
|
49
|
+
o.b.should be_a_kind_of(Sequel::SQL::Blob)
|
50
|
+
o.b.should == Sequel.blob(' name ')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should work correctly for dataset changes" do
|
54
|
+
c = Class.new(Sequel::Model(@db[:test]))
|
55
|
+
c.plugin :string_stripper
|
56
|
+
def @db.schema(*) [[:name, {}], [:b, {:type=>:blob}]] end
|
57
|
+
c.set_dataset(@db[:test2])
|
58
|
+
o = c.new
|
59
|
+
o.name = ' name '
|
60
|
+
o.name.should == 'name'
|
61
|
+
o.b = ' name '
|
62
|
+
o.b.should be_a_kind_of(Sequel::SQL::Blob)
|
63
|
+
o.b.should == Sequel.blob(' name ')
|
64
|
+
end
|
23
65
|
end
|
@@ -608,7 +608,7 @@ describe "Sequel::Model Simple Associations" do
|
|
608
608
|
@els = {:eager_limit_strategy=>:correlated_subquery}
|
609
609
|
end
|
610
610
|
it_should_behave_like "eager limit strategies"
|
611
|
-
end unless Sequel.guarded?(:mysql, :db2, :oracle, :h2, :cubrid)
|
611
|
+
end unless Sequel.guarded?(:mysql, :db2, :oracle, :h2, :cubrid, :hsqldb)
|
612
612
|
|
613
613
|
specify "should handle many_to_one associations with same name as :key" do
|
614
614
|
Album.def_column_alias(:artist_id_id, :artist_id)
|
@@ -821,7 +821,7 @@ describe "Sequel::Model Composite Key Associations" do
|
|
821
821
|
@els = {:eager_limit_strategy=>:correlated_subquery}
|
822
822
|
end
|
823
823
|
it_should_behave_like "eager limit strategies"
|
824
|
-
end if INTEGRATION_DB.dataset.supports_multiple_column_in? && !Sequel.guarded?(:mysql, :db2, :oracle)
|
824
|
+
end if INTEGRATION_DB.dataset.supports_multiple_column_in? && !Sequel.guarded?(:mysql, :db2, :oracle, :hsqldb)
|
825
825
|
|
826
826
|
specify "should have add method accept hashes and create new records" do
|
827
827
|
@artist.remove_all_albums
|
@@ -2017,3 +2017,93 @@ describe "Sequel::Plugins::ConstraintValidations" do
|
|
2017
2017
|
it_should_behave_like "constraint validations"
|
2018
2018
|
end
|
2019
2019
|
end
|
2020
|
+
|
2021
|
+
describe "date_arithmetic extension" do
|
2022
|
+
asd = begin
|
2023
|
+
require 'active_support/duration'
|
2024
|
+
require 'active_support/inflector'
|
2025
|
+
require 'active_support/core_ext/string/inflections'
|
2026
|
+
true
|
2027
|
+
rescue LoadError
|
2028
|
+
false
|
2029
|
+
end
|
2030
|
+
|
2031
|
+
before(:all) do
|
2032
|
+
@db = INTEGRATION_DB
|
2033
|
+
@db.extension(:date_arithmetic)
|
2034
|
+
if @db.database_type == :sqlite
|
2035
|
+
@db.use_timestamp_timezones = false
|
2036
|
+
end
|
2037
|
+
@date = Date.civil(2010, 7, 12)
|
2038
|
+
@dt = Time.local(2010, 7, 12)
|
2039
|
+
if asd
|
2040
|
+
@d0 = ActiveSupport::Duration.new(0, [[:days, 0]])
|
2041
|
+
@d1 = ActiveSupport::Duration.new(1, [[:days, 1]])
|
2042
|
+
@d2 = ActiveSupport::Duration.new(1, [[:years, 1], [:months, 1], [:days, 1], [:minutes, 61], [:seconds, 1]])
|
2043
|
+
end
|
2044
|
+
@h0 = {:days=>0}
|
2045
|
+
@h1 = {:days=>1, :years=>nil, :hours=>0}
|
2046
|
+
@h2 = {:years=>1, :months=>1, :days=>1, :hours=>1, :minutes=>1, :seconds=>1}
|
2047
|
+
@a1 = Time.local(2010, 7, 13)
|
2048
|
+
@a2 = Time.local(2011, 8, 13, 1, 1, 1)
|
2049
|
+
@s1 = Time.local(2010, 7, 11)
|
2050
|
+
@s2 = Time.local(2009, 6, 10, 22, 58, 59)
|
2051
|
+
@check = lambda do |meth, in_date, in_interval, should|
|
2052
|
+
output = @db.get(Sequel.send(meth, in_date, in_interval))
|
2053
|
+
output = Time.parse(output.to_s) unless output.is_a?(Time) || output.is_a?(DateTime)
|
2054
|
+
output.year.should == should.year
|
2055
|
+
output.month.should == should.month
|
2056
|
+
output.day.should == should.day
|
2057
|
+
output.hour.should == should.hour
|
2058
|
+
output.min.should == should.min
|
2059
|
+
output.sec.should == should.sec
|
2060
|
+
end
|
2061
|
+
end
|
2062
|
+
after(:all) do
|
2063
|
+
if @db.database_type == :sqlite
|
2064
|
+
@db.use_timestamp_timezones = true
|
2065
|
+
end
|
2066
|
+
end
|
2067
|
+
|
2068
|
+
if asd
|
2069
|
+
specify "be able to use Sequel.date_add to add ActiveSupport::Duration objects to dates and datetimes" do
|
2070
|
+
@check.call(:date_add, @date, @d0, @dt)
|
2071
|
+
@check.call(:date_add, @date, @d1, @a1)
|
2072
|
+
@check.call(:date_add, @date, @d2, @a2)
|
2073
|
+
|
2074
|
+
@check.call(:date_add, @dt, @d0, @dt)
|
2075
|
+
@check.call(:date_add, @dt, @d1, @a1)
|
2076
|
+
@check.call(:date_add, @dt, @d2, @a2)
|
2077
|
+
end
|
2078
|
+
|
2079
|
+
specify "be able to use Sequel.date_sub to subtract ActiveSupport::Duration objects from dates and datetimes" do
|
2080
|
+
@check.call(:date_sub, @date, @d0, @dt)
|
2081
|
+
@check.call(:date_sub, @date, @d1, @s1)
|
2082
|
+
@check.call(:date_sub, @date, @d2, @s2)
|
2083
|
+
|
2084
|
+
@check.call(:date_sub, @dt, @d0, @dt)
|
2085
|
+
@check.call(:date_sub, @dt, @d1, @s1)
|
2086
|
+
@check.call(:date_sub, @dt, @d2, @s2)
|
2087
|
+
end
|
2088
|
+
end
|
2089
|
+
|
2090
|
+
specify "be able to use Sequel.date_add to add interval hashes to dates and datetimes" do
|
2091
|
+
@check.call(:date_add, @date, @h0, @dt)
|
2092
|
+
@check.call(:date_add, @date, @h1, @a1)
|
2093
|
+
@check.call(:date_add, @date, @h2, @a2)
|
2094
|
+
|
2095
|
+
@check.call(:date_add, @dt, @h0, @dt)
|
2096
|
+
@check.call(:date_add, @dt, @h1, @a1)
|
2097
|
+
@check.call(:date_add, @dt, @h2, @a2)
|
2098
|
+
end
|
2099
|
+
|
2100
|
+
specify "be able to use Sequel.date_sub to subtract interval hashes from dates and datetimes" do
|
2101
|
+
@check.call(:date_sub, @date, @h0, @dt)
|
2102
|
+
@check.call(:date_sub, @date, @h1, @s1)
|
2103
|
+
@check.call(:date_sub, @date, @h2, @s2)
|
2104
|
+
|
2105
|
+
@check.call(:date_sub, @dt, @h0, @dt)
|
2106
|
+
@check.call(:date_sub, @dt, @h1, @s1)
|
2107
|
+
@check.call(:date_sub, @dt, @h2, @s2)
|
2108
|
+
end
|
2109
|
+
end
|
@@ -382,7 +382,7 @@ describe "Database schema modifiers" do
|
|
382
382
|
proc{@ds.insert(10)}.should_not raise_error
|
383
383
|
end
|
384
384
|
|
385
|
-
|
385
|
+
cspecify "should add foreign key columns to tables correctly", :hsqldb do
|
386
386
|
@db.create_table!(:items){primary_key :id}
|
387
387
|
@ds.insert
|
388
388
|
i = @ds.get(:id)
|
@@ -190,7 +190,7 @@ end
|
|
190
190
|
describe Sequel::Model::Associations::AssociationReflection do
|
191
191
|
before do
|
192
192
|
@c = Class.new(Sequel::Model(:foo))
|
193
|
-
@c.
|
193
|
+
def @c.name() "C" end
|
194
194
|
end
|
195
195
|
|
196
196
|
it "#eager_loading_predicate_key should be an alias of predicate_key for backwards compatibility" do
|
@@ -276,13 +276,13 @@ describe Sequel::Model::Associations::AssociationReflection, "#eager_limit_strat
|
|
276
276
|
end
|
277
277
|
|
278
278
|
it "should use :distinct_on for one_to_one associations if picking and the association dataset supports ordered distinct on" do
|
279
|
-
@c.dataset.
|
279
|
+
def (@c.dataset).supports_ordered_distinct_on?() true end
|
280
280
|
@c.one_to_one :c, :class=>@c, :eager_limit_strategy=>true
|
281
281
|
@c.association_reflection(:c).eager_limit_strategy.should == :distinct_on
|
282
282
|
end
|
283
283
|
|
284
284
|
it "should use :window_function for associations if picking and the association dataset supports window functions" do
|
285
|
-
@c.dataset.
|
285
|
+
def (@c.dataset).supports_window_functions?() true end
|
286
286
|
@c.one_to_one :c, :class=>@c, :eager_limit_strategy=>true
|
287
287
|
@c.association_reflection(:c).eager_limit_strategy.should == :window_function
|
288
288
|
@c.one_to_many :cs, :class=>@c, :eager_limit_strategy=>true, :limit=>1
|
@@ -314,7 +314,7 @@ describe Sequel::Model::Associations::AssociationReflection, "#eager_limit_strat
|
|
314
314
|
c.dataset = :a
|
315
315
|
c.one_to_many :cs, :class=>c, :limit=>1
|
316
316
|
c.association_reflection(:cs).eager_limit_strategy.should == :ruby
|
317
|
-
c.dataset.
|
317
|
+
def (c.dataset).supports_window_functions?() true end
|
318
318
|
c.many_to_many :cs, :class=>c, :limit=>1
|
319
319
|
c.association_reflection(:cs).eager_limit_strategy.should == :window_function
|
320
320
|
|
@@ -602,7 +602,7 @@ describe Sequel::Model, "many_to_one" do
|
|
602
602
|
c = @c2.load(:id=>123)
|
603
603
|
p.raise_on_save_failure = false
|
604
604
|
@c2.many_to_one :parent, :class => @c2, :before_set=>:bs
|
605
|
-
p.
|
605
|
+
def p.bs(x) false end
|
606
606
|
p.should_not_receive(:_parent=)
|
607
607
|
proc{p.parent = c}.should raise_error(Sequel::Error)
|
608
608
|
|
@@ -1038,7 +1038,7 @@ describe Sequel::Model, "one_to_one" do
|
|
1038
1038
|
c = @c2.load(:id=>123)
|
1039
1039
|
p.raise_on_save_failure = false
|
1040
1040
|
@c2.one_to_one :parent, :class => @c2, :before_set=>:bs
|
1041
|
-
p.
|
1041
|
+
def p.bs(x) false end
|
1042
1042
|
p.should_not_receive(:_parent=)
|
1043
1043
|
proc{p.parent = c}.should raise_error(Sequel::Error)
|
1044
1044
|
|
data/spec/model/base_spec.rb
CHANGED
@@ -588,9 +588,9 @@ end
|
|
588
588
|
describe Sequel::Model, ".require_modification" do
|
589
589
|
before do
|
590
590
|
@ds1 = MODEL_DB[:items]
|
591
|
-
@ds1.
|
591
|
+
def @ds1.provides_accurate_rows_matched?() false end
|
592
592
|
@ds2 = MODEL_DB[:items]
|
593
|
-
@ds2.
|
593
|
+
def @ds2.provides_accurate_rows_matched?() true end
|
594
594
|
end
|
595
595
|
after do
|
596
596
|
Sequel::Model.require_modification = nil
|
@@ -150,7 +150,7 @@ describe Sequel::Model, "#eager" do
|
|
150
150
|
end
|
151
151
|
|
152
152
|
it "should eagerly load a single one_to_one association using the :distinct_on strategy" do
|
153
|
-
EagerTrack.dataset.
|
153
|
+
def (EagerTrack.dataset).supports_distinct_on?() true end
|
154
154
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true
|
155
155
|
a = EagerAlbum.eager(:track).all
|
156
156
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -160,7 +160,7 @@ describe Sequel::Model, "#eager" do
|
|
160
160
|
end
|
161
161
|
|
162
162
|
it "should eagerly load a single one_to_one association using the :window_function strategy" do
|
163
|
-
EagerTrack.dataset.
|
163
|
+
def (EagerTrack.dataset).supports_window_functions?() true end
|
164
164
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true, :order=>:name
|
165
165
|
a = EagerAlbum.eager(:track).all
|
166
166
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -562,7 +562,7 @@ describe Sequel::Model, "#eager" do
|
|
562
562
|
end
|
563
563
|
|
564
564
|
it "should respect the :limit option on a one_to_many association using the :window_function strategy" do
|
565
|
-
EagerTrack.dataset.
|
565
|
+
def (EagerTrack.dataset).supports_window_functions?() true end
|
566
566
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true, :order=>:name, :limit=>2
|
567
567
|
a = EagerAlbum.eager(:tracks).all
|
568
568
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -572,7 +572,7 @@ describe Sequel::Model, "#eager" do
|
|
572
572
|
end
|
573
573
|
|
574
574
|
it "should respect the :limit option with an offset on a one_to_many association using the :window_function strategy" do
|
575
|
-
EagerTrack.dataset.
|
575
|
+
def (EagerTrack.dataset).supports_window_functions?() true end
|
576
576
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true, :order=>:name, :limit=>[2, 1]
|
577
577
|
a = EagerAlbum.eager(:tracks).all
|
578
578
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -616,7 +616,7 @@ describe Sequel::Model, "#eager" do
|
|
616
616
|
end
|
617
617
|
|
618
618
|
it "should respect the limit option on a many_to_many association using the :window_function strategy" do
|
619
|
-
EagerGenre.dataset.
|
619
|
+
def (EagerGenre.dataset).supports_window_functions?() true end
|
620
620
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>true, :limit=>2, :order=>:name
|
621
621
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
622
622
|
as = EagerAlbum.eager(:first_two_genres).all
|