sequel 4.47.0 → 4.48.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.
- checksums.yaml +4 -4
- data/CHANGELOG +134 -0
- data/Rakefile +1 -1
- data/doc/release_notes/4.48.0.txt +293 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +24 -7
- data/lib/sequel/adapters/jdbc.rb +36 -22
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
- data/lib/sequel/adapters/mock.rb +24 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +4 -5
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +89 -102
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +75 -24
- data/lib/sequel/adapters/shared/postgres.rb +196 -94
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +18 -10
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +19 -8
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +6 -6
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +24 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model.rb +25 -57
- data/lib/sequel/model/associations.rb +14 -5
- data/lib/sequel/model/base.rb +96 -32
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +1 -1
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/defaults_setter.rb +10 -0
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +17 -10
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +5 -1
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/serialization.rb +3 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +2 -4
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mysql_spec.rb +78 -28
- data/spec/adapters/oracle_spec.rb +24 -24
- data/spec/adapters/postgres_spec.rb +38 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/core/connection_pool_spec.rb +17 -0
- data/spec/core/database_spec.rb +6 -0
- data/spec/core/dataset_spec.rb +46 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +48 -2
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +8 -8
- data/spec/extensions/defaults_setter_spec.rb +1 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +96 -98
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +9 -3
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/plugin_test.rb +20 -0
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/class_dataset_methods_spec.rb +14 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/model_spec.rb +8 -0
- metadata +6 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
data/spec/core/spec_helper.rb
CHANGED
|
@@ -19,6 +19,7 @@ require 'minitest/shared_description'
|
|
|
19
19
|
require "#{File.dirname(File.dirname(__FILE__))}/deprecation_helper.rb"
|
|
20
20
|
|
|
21
21
|
class Minitest::HooksSpec
|
|
22
|
+
# SEQUEL5: Replace with define_singleton_method
|
|
22
23
|
def meta_def(obj, name, &block)
|
|
23
24
|
(class << obj; self end).send(:define_method, name, &block)
|
|
24
25
|
end
|
|
@@ -316,13 +316,17 @@ describe "Array#sql_value_list and #sql_array" do
|
|
|
316
316
|
it "should treat the array as an SQL value list instead of conditions when used as a placeholder value" do
|
|
317
317
|
@d.filter(Sequel.lit("(a, b) IN ?", [[:x, 1], [:y, 2]])).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x = 1) AND (y = 2)))'
|
|
318
318
|
@d.filter(Sequel.lit("(a, b) IN ?", [[:x, 1], [:y, 2]].sql_value_list)).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
|
319
|
-
|
|
319
|
+
deprecated do
|
|
320
|
+
@d.filter(Sequel.lit("(a, b) IN ?", [[:x, 1], [:y, 2]].sql_array)).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
|
321
|
+
end
|
|
320
322
|
end
|
|
321
323
|
|
|
322
324
|
it "should be no difference when used as a hash value" do
|
|
323
325
|
@d.filter([:a, :b]=>[[:x, 1], [:y, 2]]).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
|
324
326
|
@d.filter([:a, :b]=>[[:x, 1], [:y, 2]].sql_value_list).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
|
325
|
-
|
|
327
|
+
deprecated do
|
|
328
|
+
@d.filter([:a, :b]=>[[:x, 1], [:y, 2]].sql_array).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
|
329
|
+
end
|
|
326
330
|
end
|
|
327
331
|
end
|
|
328
332
|
|
|
@@ -33,7 +33,7 @@ describe "arbtirary servers" do
|
|
|
33
33
|
|
|
34
34
|
it "should disconnect when connection is finished" do
|
|
35
35
|
x, x1 = nil, nil
|
|
36
|
-
@db
|
|
36
|
+
meta_def(@db, :disconnect_connection){|c| x = c}
|
|
37
37
|
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
|
38
38
|
x1 = c
|
|
39
39
|
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
|
@@ -8,7 +8,8 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
8
8
|
{:id=>$1.to_i}
|
|
9
9
|
when "SELECT id FROM albums WHERE (albums.artist_id = 1)"
|
|
10
10
|
[{:id=>1}, {:id=>2}, {:id=>3}]
|
|
11
|
-
when /SELECT tag_id FROM albums_tags WHERE \(album_id = (\d)\)
|
|
11
|
+
when /SELECT tag_id FROM albums_tags WHERE \(album_id = (\d)\)/,
|
|
12
|
+
/SELECT tags.id FROM tags INNER JOIN albums_tags ON \(albums_tags.tag_id = tags.id\) WHERE \(albums_tags.album_id = (\d)\)/
|
|
12
13
|
a = []
|
|
13
14
|
a << {:tag_id=>1} if $1 == '1'
|
|
14
15
|
a << {:tag_id=>2} if $1 != '3'
|
|
@@ -32,7 +33,8 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
32
33
|
a
|
|
33
34
|
when "SELECT year, week FROM hits WHERE ((hits.first = 'F1') AND (hits.last = 'L1'))"
|
|
34
35
|
[{:year=>1997, :week=>1}, {:year=>1997, :week=>2}]
|
|
35
|
-
when /SELECT year, week FROM vocalists_hits WHERE \(\((?:first|last) = '?[FL1](\d)
|
|
36
|
+
when /SELECT year, week FROM vocalists_hits WHERE \(\((?:first|last) = '?[FL1](\d)/,
|
|
37
|
+
/SELECT hits.year, hits.week FROM hits INNER JOIN vocalists_hits ON \(\(vocalists_hits.(?:year|week) = hits.(?:year|week)\) AND \(vocalists_hits.(?:year|week) = hits.(?:year|week)\)\) WHERE \(\(vocalists_hits.(?:first|last) = '?[FL1](\d)/
|
|
36
38
|
a = []
|
|
37
39
|
a << {:year=>1997, :week=>1} if $1 == "1"
|
|
38
40
|
a << {:year=>1997, :week=>2} if $1 != "3"
|
|
@@ -64,13 +66,28 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
64
66
|
|
|
65
67
|
it "should return correct associated pks for one_to_many associations" do
|
|
66
68
|
@Artist.load(:id=>1).album_pks.must_equal [1,2,3]
|
|
69
|
+
@db.sqls.must_equal ["SELECT id FROM albums WHERE (albums.artist_id = 1)"]
|
|
67
70
|
@Artist.load(:id=>2).album_pks.must_equal []
|
|
71
|
+
@db.sqls.must_equal ["SELECT id FROM albums WHERE (albums.artist_id = 2)"]
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
it "should return correct associated pks for many_to_many associations" do
|
|
71
75
|
@Album.load(:id=>1).tag_pks.must_equal [1, 2]
|
|
76
|
+
@db.sqls.must_equal ["SELECT tag_id FROM albums_tags WHERE (album_id = 1)"]
|
|
72
77
|
@Album.load(:id=>2).tag_pks.must_equal [2, 3]
|
|
78
|
+
@db.sqls.must_equal ["SELECT tag_id FROM albums_tags WHERE (album_id = 2)"]
|
|
73
79
|
@Album.load(:id=>3).tag_pks.must_equal []
|
|
80
|
+
@db.sqls.must_equal ["SELECT tag_id FROM albums_tags WHERE (album_id = 3)"]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "should return correct associated pks for many_to_many associations using :association_pks_use_associated_table" do
|
|
84
|
+
@Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id, :delay_pks=>false, :association_pks_use_associated_table=>true
|
|
85
|
+
@Album.load(:id=>1).tag_pks.must_equal [1, 2]
|
|
86
|
+
@db.sqls.must_equal ["SELECT tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE (albums_tags.album_id = 1)"]
|
|
87
|
+
@Album.load(:id=>2).tag_pks.must_equal [2, 3]
|
|
88
|
+
@db.sqls.must_equal ["SELECT tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE (albums_tags.album_id = 2)"]
|
|
89
|
+
@Album.load(:id=>3).tag_pks.must_equal []
|
|
90
|
+
@db.sqls.must_equal ["SELECT tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE (albums_tags.album_id = 3)"]
|
|
74
91
|
end
|
|
75
92
|
|
|
76
93
|
deprecated "should set associated pks correctly for a one_to_many association when :delay_pks is not set" do
|
|
@@ -171,14 +188,29 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
171
188
|
it "should return correct right-side associated cpks for left-side cpks for one_to_many associations" do
|
|
172
189
|
@Vocalist.one_to_many :hits, :class=>@Hit, :key=>[:first, :last]
|
|
173
190
|
@Vocalist.load(:first=>'F1', :last=>'L1').hit_pks.must_equal [[1997, 1], [1997, 2]]
|
|
191
|
+
@db.sqls.must_equal ["SELECT year, week FROM hits WHERE ((hits.first = 'F1') AND (hits.last = 'L1'))"]
|
|
174
192
|
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks.must_equal []
|
|
193
|
+
@db.sqls.must_equal ["SELECT year, week FROM hits WHERE ((hits.first = 'F2') AND (hits.last = 'L2'))"]
|
|
175
194
|
end
|
|
176
195
|
|
|
177
196
|
it "should return correct right-side associated cpks for left-side cpks for many_to_many associations" do
|
|
178
197
|
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week]
|
|
179
198
|
@Vocalist.load(:first=>'F1', :last=>'L1').hit_pks.must_equal [[1997, 1], [1997, 2]]
|
|
199
|
+
@db.sqls.must_equal ["SELECT year, week FROM vocalists_hits WHERE ((first = 'F1') AND (last = 'L1'))"]
|
|
200
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks.must_equal [[1997, 2], [1997, 3]]
|
|
201
|
+
@db.sqls.must_equal ["SELECT year, week FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2'))"]
|
|
202
|
+
@Vocalist.load(:first=>'F3', :last=>'L3').hit_pks.must_equal []
|
|
203
|
+
@db.sqls.must_equal ["SELECT year, week FROM vocalists_hits WHERE ((first = 'F3') AND (last = 'L3'))"]
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "should return correct right-side associated cpks for left-side cpks for many_to_many associations when using :association_pks_use_associated_table" do
|
|
207
|
+
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week], :association_pks_use_associated_table=>true
|
|
208
|
+
@Vocalist.load(:first=>'F1', :last=>'L1').hit_pks.must_equal [[1997, 1], [1997, 2]]
|
|
209
|
+
@db.sqls.must_equal ["SELECT hits.year, hits.week FROM hits INNER JOIN vocalists_hits ON ((vocalists_hits.year = hits.year) AND (vocalists_hits.week = hits.week)) WHERE ((vocalists_hits.first = 'F1') AND (vocalists_hits.last = 'L1'))"]
|
|
180
210
|
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks.must_equal [[1997, 2], [1997, 3]]
|
|
211
|
+
@db.sqls.must_equal ["SELECT hits.year, hits.week FROM hits INNER JOIN vocalists_hits ON ((vocalists_hits.year = hits.year) AND (vocalists_hits.week = hits.week)) WHERE ((vocalists_hits.first = 'F2') AND (vocalists_hits.last = 'L2'))"]
|
|
181
212
|
@Vocalist.load(:first=>'F3', :last=>'L3').hit_pks.must_equal []
|
|
213
|
+
@db.sqls.must_equal ["SELECT hits.year, hits.week FROM hits INNER JOIN vocalists_hits ON ((vocalists_hits.year = hits.year) AND (vocalists_hits.week = hits.week)) WHERE ((vocalists_hits.first = 'F3') AND (vocalists_hits.last = 'L3'))"]
|
|
182
214
|
end
|
|
183
215
|
|
|
184
216
|
it "should set associated right-side cpks correctly for left-side cpks for a one_to_many association" do
|
|
@@ -9,6 +9,10 @@ describe "Dataset#where" do
|
|
|
9
9
|
@dataset.where('price < ? AND id in ?', 100, [1, 2, 3]).select_sql.must_equal "SELECT * FROM test WHERE (price < 100 AND id in (1, 2, 3))"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
it "should use default behavior for array of conditions" do
|
|
13
|
+
@dataset.where([[:a, 1], [:b, 2]]).sql.must_equal 'SELECT * FROM test WHERE ((a = 1) AND (b = 2))'
|
|
14
|
+
end
|
|
15
|
+
|
|
12
16
|
it "should not modify passed array with placeholders" do
|
|
13
17
|
a = ['price < ? AND id in ?', 100, 1, 2, 3]
|
|
14
18
|
b = a.dup
|
|
@@ -114,7 +118,7 @@ describe "Dataset#and" do
|
|
|
114
118
|
@d1 = @dataset.where(:x => 1)
|
|
115
119
|
end
|
|
116
120
|
|
|
117
|
-
|
|
121
|
+
deprecated "should accept string filters with placeholders" do
|
|
118
122
|
@d1.and('y > ?', 2).sql.must_equal 'SELECT * FROM test WHERE ((x = 1) AND (y > 2))'
|
|
119
123
|
end
|
|
120
124
|
end
|
|
@@ -86,7 +86,7 @@ describe Sequel::Model, "BooleanReaders plugin" do
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
it "should handle cases where getting the columns raises an error" do
|
|
89
|
-
@c.
|
|
89
|
+
def @c.columns; raise Sequel::Error end
|
|
90
90
|
@c.plugin(:boolean_readers)
|
|
91
91
|
proc{@c.new.b?}.must_raise(NoMethodError)
|
|
92
92
|
end
|
|
@@ -40,7 +40,7 @@ describe "boolean_subsets plugin" do
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "should handle cases where getting the columns raises an error" do
|
|
43
|
-
@c.
|
|
43
|
+
def @c.columns; raise Sequel::Error end
|
|
44
44
|
@c.plugin(:boolean_subsets)
|
|
45
45
|
@c.respond_to?(:active).must_equal false
|
|
46
46
|
end
|
|
@@ -62,6 +62,11 @@ describe "class_table_inheritance plugin" do
|
|
|
62
62
|
Employee.cti_table_map.frozen?.must_equal true
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
deprecated "should support cti_key and cti_model_map" do
|
|
66
|
+
Employee.cti_key.must_equal Employee.sti_key
|
|
67
|
+
Employee.cti_model_map.must_equal Employee.sti_model_map
|
|
68
|
+
end
|
|
69
|
+
|
|
65
70
|
deprecated "should not attempt to use prepared statements" do
|
|
66
71
|
Manager.plugin :prepared_statements
|
|
67
72
|
Manager[1]
|
|
@@ -572,10 +577,14 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
572
577
|
@db.sqls.must_equal ["SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 1) LIMIT 1"]
|
|
573
578
|
end
|
|
574
579
|
|
|
575
|
-
|
|
580
|
+
deprecated "#cti_base_model should be the model that loaded the plugin" do
|
|
576
581
|
Executive.cti_base_model.must_equal Employee
|
|
577
582
|
end
|
|
578
583
|
|
|
584
|
+
it "#cti_models.first should be the model that loaded the plugin" do
|
|
585
|
+
Executive.cti_models.first.must_equal Employee
|
|
586
|
+
end
|
|
587
|
+
|
|
579
588
|
it "#cti_columns should be a mapping of table names to columns" do
|
|
580
589
|
Executive.cti_columns.must_equal(:employees=>[:id, :name, :kind], :managers=>[:id, :num_staff], :executives=>[:id, :num_managers])
|
|
581
590
|
end
|
|
@@ -668,6 +677,39 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
668
677
|
"INSERT INTO executives (id) VALUES (1)"]
|
|
669
678
|
end
|
|
670
679
|
|
|
680
|
+
it "should sets the model class name for the key when creating new subclass records" do
|
|
681
|
+
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
|
682
|
+
Object.send(:remove_const, :Ceo)
|
|
683
|
+
Object.send(:remove_const, :Executive)
|
|
684
|
+
Object.send(:remove_const, :Manager)
|
|
685
|
+
class ::Manager < Employee; end
|
|
686
|
+
class ::Executive < Manager; end
|
|
687
|
+
class ::Ceo < Executive; end
|
|
688
|
+
Ceo.create
|
|
689
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('3')",
|
|
690
|
+
"INSERT INTO managers (id) VALUES (1)",
|
|
691
|
+
"INSERT INTO executives (id) VALUES (1)"]
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
it "should sets the model class name for the key when creating new subclass records" do
|
|
695
|
+
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
|
696
|
+
Object.send(:remove_const, :Ceo)
|
|
697
|
+
Object.send(:remove_const, :Executive)
|
|
698
|
+
Object.send(:remove_const, :Manager)
|
|
699
|
+
class ::Manager < Employee; end
|
|
700
|
+
class ::Executive < Employee; end
|
|
701
|
+
class ::Ceo < Employee; end
|
|
702
|
+
Ceo.create
|
|
703
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('3')"]
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
it "should not use a subquery for a class that doesn't join to a separate table" do
|
|
707
|
+
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
|
708
|
+
Object.send(:remove_const, :Ceo)
|
|
709
|
+
class ::Ceo < Employee; end
|
|
710
|
+
Ceo.dataset.sql.must_equal 'SELECT * FROM employees WHERE (employees.kind IN (3))'
|
|
711
|
+
end
|
|
712
|
+
|
|
671
713
|
it "should ignore existing cti_key value when creating new records" do
|
|
672
714
|
Employee.create(:kind=>'Manager')
|
|
673
715
|
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
@@ -1069,10 +1111,14 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1069
1111
|
@db.sqls.must_equal ["SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 1) LIMIT 1"]
|
|
1070
1112
|
end
|
|
1071
1113
|
|
|
1072
|
-
|
|
1114
|
+
deprecated "#cti_base_model should be the model that loaded the plugin" do
|
|
1073
1115
|
Executive.cti_base_model.must_equal Employee
|
|
1074
1116
|
end
|
|
1075
1117
|
|
|
1118
|
+
it "#cti_models.first should be the model that loaded the plugin" do
|
|
1119
|
+
Executive.cti_models.first.must_equal Employee
|
|
1120
|
+
end
|
|
1121
|
+
|
|
1076
1122
|
it "#cti_columns should be a mapping of table names to columns" do
|
|
1077
1123
|
Executive.cti_columns.must_equal(:employees=>[:id, :name, :kind], :managers=>[:id, :num_staff], :executives=>[:id, :num_managers])
|
|
1078
1124
|
end
|
|
@@ -39,6 +39,17 @@ describe "column_conflicts plugin" do
|
|
|
39
39
|
@o.get_column_value(:model).must_equal 2
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
it "should not erase existing column conflicts when loading the plugin" do
|
|
43
|
+
@c.send(:define_method, :foo){raise}
|
|
44
|
+
@c.send(:define_method, :model=){raise}
|
|
45
|
+
@c.get_column_conflict!(:foo)
|
|
46
|
+
@c.set_column_conflict!(:model)
|
|
47
|
+
@c.plugin :column_conflicts
|
|
48
|
+
@o.get_column_value(:foo).must_equal 4
|
|
49
|
+
@o.set_column_value(:model=, 2).must_equal 2
|
|
50
|
+
@o.get_column_value(:model).must_equal 2
|
|
51
|
+
end
|
|
52
|
+
|
|
42
53
|
it "should work correctly in subclasses" do
|
|
43
54
|
@o = Class.new(@c).load(:model=>1, :use_transactions=>2)
|
|
44
55
|
@o.get_column_value(:model).must_equal 1
|
|
@@ -104,7 +104,7 @@ connection_validator_specs = shared_description do
|
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
it "should handle case where determining validity requires a connection" do
|
|
107
|
-
@db.
|
|
107
|
+
def @db.valid_connection?(c) synchronize{}; true end
|
|
108
108
|
@db.pool.connection_validation_timeout = -1
|
|
109
109
|
c1 = @db.synchronize{|c| c}
|
|
110
110
|
@db.synchronize{|c| c}.must_be_same_as(c1)
|
|
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "Sequel::Plugins::DatasetAssociations" do
|
|
4
4
|
before do
|
|
5
|
-
@db = Sequel.mock
|
|
5
|
+
@db = Sequel.mock(:host=>'postgres')
|
|
6
6
|
@db.extend_datasets do
|
|
7
7
|
def supports_window_functions?; true; end
|
|
8
8
|
def supports_distinct_on?; true; end
|
|
@@ -14,9 +14,9 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
|
14
14
|
@Album = Class.new(@Base)
|
|
15
15
|
@Tag = Class.new(@Base)
|
|
16
16
|
|
|
17
|
-
@Artist.
|
|
18
|
-
@Album.
|
|
19
|
-
@Tag.
|
|
17
|
+
def @Artist.name; 'Artist' end
|
|
18
|
+
def @Album.name; 'Album' end
|
|
19
|
+
def @Tag.name; 'Tag' end
|
|
20
20
|
|
|
21
21
|
@Artist.dataset = @db[:artists]
|
|
22
22
|
@Album.dataset = @db[:albums]
|
|
@@ -142,7 +142,7 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
|
142
142
|
ds = @Tag.artists
|
|
143
143
|
ds.must_be_kind_of(Sequel::Dataset)
|
|
144
144
|
ds.model.must_equal @Artist
|
|
145
|
-
ds.sql.must_equal "SELECT * FROM artists WHERE coalesce((tag_ids && (SELECT array_agg(tags.id) FROM tags)),
|
|
145
|
+
ds.sql.must_equal "SELECT * FROM artists WHERE coalesce((tag_ids && (SELECT array_agg(tags.id) FROM tags)), false)"
|
|
146
146
|
end
|
|
147
147
|
|
|
148
148
|
it "should have an associated method that takes an association symbol" do
|
|
@@ -261,9 +261,9 @@ describe "Sequel::Plugins::DatasetAssociations with composite keys" do
|
|
|
261
261
|
@Album = Class.new(@Base)
|
|
262
262
|
@Tag = Class.new(@Base)
|
|
263
263
|
|
|
264
|
-
@Artist.
|
|
265
|
-
@Album.
|
|
266
|
-
@Tag.
|
|
264
|
+
def @Artist.name; 'Artist' end
|
|
265
|
+
def @Album.name; 'Album' end
|
|
266
|
+
def @Tag.name; 'Tag' end
|
|
267
267
|
|
|
268
268
|
@Artist.dataset = @db[:artists]
|
|
269
269
|
@Album.dataset = @db[:albums]
|
|
@@ -9,7 +9,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
|
9
9
|
@c.instance_variable_set(:@db_schema, {:a=>{}})
|
|
10
10
|
@c.plugin :defaults_setter
|
|
11
11
|
@c.columns :a
|
|
12
|
-
@pr = proc{|x|
|
|
12
|
+
@pr = proc{|x| meta_def(db, :schema){|*| [[:id, {:primary_key=>true}], [:a, {:ruby_default => x, :primary_key=>false}]]}; c.dataset = c.dataset; c}
|
|
13
13
|
end
|
|
14
14
|
after do
|
|
15
15
|
Sequel.datetime_class = Time
|
|
@@ -2,7 +2,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "filter_having extension" do
|
|
4
4
|
before do
|
|
5
|
-
|
|
5
|
+
deprecated do
|
|
6
|
+
@ds = Sequel.mock[:t].extension(:filter_having)
|
|
7
|
+
end
|
|
6
8
|
@dsh = @ds.having(:a)
|
|
7
9
|
end
|
|
8
10
|
|
|
@@ -14,11 +16,11 @@ describe "filter_having extension" do
|
|
|
14
16
|
@ds.filter(:b).sql.must_equal 'SELECT * FROM t WHERE b'
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
deprecated "should make and operate on HAVING clause if dataset has a HAVING clause" do
|
|
18
20
|
@dsh.and(:b).sql.must_equal 'SELECT * FROM t HAVING (a AND b)'
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
deprecated "should make and operate on WHERE clause if dataset does not have a HAVING clause" do
|
|
22
24
|
@ds.where(:a).and(:b).sql.must_equal 'SELECT * FROM t WHERE (a AND b)'
|
|
23
25
|
end
|
|
24
26
|
|
|
@@ -2,7 +2,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "hash_aliases extension" do
|
|
4
4
|
before do
|
|
5
|
-
|
|
5
|
+
deprecated do
|
|
6
|
+
@ds = Sequel.mock.dataset.extension(:hash_aliases)
|
|
7
|
+
end
|
|
6
8
|
end
|
|
7
9
|
|
|
8
10
|
it "should make from treat hash arguments as alias specifiers" do
|
|
@@ -9,13 +9,15 @@ describe "Sequel::Dataset::ImplicitSubquery" do
|
|
|
9
9
|
ods = db[:c]
|
|
10
10
|
ods.columns(:id, :b)
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
deprecated do
|
|
13
|
+
ds.and(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE c"
|
|
14
|
+
ds.exclude_where(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE NOT c"
|
|
15
|
+
end
|
|
13
16
|
ds.cross_join(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 CROSS JOIN c"
|
|
14
17
|
ds.distinct.sql.must_equal "SELECT DISTINCT * FROM (SELECT * FROM table) AS t1"
|
|
15
18
|
ds.except(ods).sql.must_equal "SELECT * FROM (SELECT * FROM (SELECT * FROM table) AS t1 EXCEPT SELECT * FROM c) AS t1"
|
|
16
19
|
ds.exclude(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE NOT c"
|
|
17
20
|
ds.exclude_having(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 HAVING NOT c"
|
|
18
|
-
ds.exclude_where(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE NOT c"
|
|
19
21
|
ds.filter(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE c"
|
|
20
22
|
ds.for_update.sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 FOR UPDATE"
|
|
21
23
|
ds.full_join(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 FULL JOIN c"
|
|
@@ -65,6 +65,12 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
|
65
65
|
Album.from_json(@album.to_json(:include=>:artist), :associations=>:artist).artist.must_equal @artist
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
it "should have #to_json support blocks for transformations" do
|
|
69
|
+
values = {}
|
|
70
|
+
@artist.values.each{|k,v| values[k.to_s] = v}
|
|
71
|
+
Sequel.parse_json(@artist.to_json{|h| {'data'=>h}}).must_equal({'data'=>values})
|
|
72
|
+
end
|
|
73
|
+
|
|
68
74
|
it "should raise an error if attempting to parse json when providing array to non-array association or vice-versa" do
|
|
69
75
|
proc{Artist.from_json('{"albums":{"id":1,"name":"RF","artist_id":2},"id":2,"name":"YJM"}', :associations=>:albums)}.must_raise(Sequel::Error)
|
|
70
76
|
proc{Album.from_json('{"artist":[{"id":2,"name":"YJM"}],"id":1,"name":"RF","artist_id":2}', :associations=>:artist)}.must_raise(Sequel::Error)
|
|
@@ -186,6 +192,18 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
|
186
192
|
Sequel.parse_json(ds.to_json).must_equal [@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}]
|
|
187
193
|
end
|
|
188
194
|
|
|
195
|
+
it "should have class and dataset to_json method accept blocks for transformations" do
|
|
196
|
+
Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
|
197
|
+
Sequel.parse_json(Album.to_json{|h| {'data'=>h}}).must_equal('data'=>[@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}])
|
|
198
|
+
Sequel.parse_json(Album.dataset.to_json{|h| {'data'=>h}}).must_equal('data'=>[@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}])
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it "should have class and dataset to_json method support :instance_block option for instance_transformations" do
|
|
202
|
+
Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
|
203
|
+
Sequel.parse_json(Album.to_json(:instance_block=>lambda{|h| {'data'=>h}})).must_equal [{'data'=>@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}}]
|
|
204
|
+
Sequel.parse_json(Album.dataset.to_json(:instance_block=>lambda{|h| {'data'=>h}})).must_equal [{'data'=>@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}}]
|
|
205
|
+
end
|
|
206
|
+
|
|
189
207
|
it "should have dataset to_json method respect :array option for the array to use" do
|
|
190
208
|
a = Album.new(:name=>'RF', :artist_id=>3)
|
|
191
209
|
Album.array_from_json(Album.to_json(:array=>[a])).must_equal [a]
|
|
@@ -5,13 +5,13 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
|
5
5
|
before do
|
|
6
6
|
@db = Sequel.mock
|
|
7
7
|
def @db.supports_schema_parsing?() true end
|
|
8
|
-
@db.
|
|
8
|
+
def @db.schema(*a) [[:id, {:type=>:integer}], [:name,{:type=>:string}]] end
|
|
9
9
|
class ::LazyAttributesModel < Sequel::Model(@db[:la])
|
|
10
10
|
plugin :lazy_attributes
|
|
11
11
|
set_columns([:id, :name])
|
|
12
|
-
|
|
12
|
+
def self.columns; [:id, :name] end
|
|
13
13
|
lazy_attributes :name
|
|
14
|
-
|
|
14
|
+
def self.columns; [:id] end
|
|
15
15
|
set_dataset dataset.with_fetch(proc do |sql|
|
|
16
16
|
if sql !~ /WHERE/
|
|
17
17
|
if sql =~ /name/
|