sequel 3.42.0 → 3.43.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.
- 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
|