sequel 4.45.0 → 4.46.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 +108 -0
- data/doc/release_notes/4.46.0.txt +404 -0
- data/doc/security.rdoc +9 -0
- data/doc/sql.rdoc +2 -2
- data/doc/testing.rdoc +1 -1
- data/doc/validations.rdoc +1 -2
- data/lib/sequel/adapters/ado.rb +8 -3
- data/lib/sequel/adapters/ado/access.rb +8 -4
- data/lib/sequel/adapters/ado/mssql.rb +3 -1
- data/lib/sequel/adapters/amalgalite.rb +5 -0
- data/lib/sequel/adapters/cubrid.rb +16 -7
- data/lib/sequel/adapters/do.rb +7 -1
- data/lib/sequel/adapters/do/mysql.rb +8 -4
- data/lib/sequel/adapters/ibmdb.rb +10 -5
- data/lib/sequel/adapters/jdbc.rb +8 -2
- data/lib/sequel/adapters/jdbc/as400.rb +10 -3
- data/lib/sequel/adapters/jdbc/db2.rb +27 -16
- data/lib/sequel/adapters/jdbc/derby.rb +47 -20
- data/lib/sequel/adapters/jdbc/h2.rb +13 -7
- data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
- data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
- data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
- data/lib/sequel/adapters/mock.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +8 -1
- data/lib/sequel/adapters/mysql2.rb +6 -1
- data/lib/sequel/adapters/odbc.rb +20 -8
- data/lib/sequel/adapters/odbc/mssql.rb +6 -3
- data/lib/sequel/adapters/oracle.rb +12 -6
- data/lib/sequel/adapters/postgres.rb +20 -8
- data/lib/sequel/adapters/shared/access.rb +76 -47
- data/lib/sequel/adapters/shared/cubrid.rb +16 -11
- data/lib/sequel/adapters/shared/db2.rb +46 -19
- data/lib/sequel/adapters/shared/firebird.rb +20 -8
- data/lib/sequel/adapters/shared/informix.rb +6 -3
- data/lib/sequel/adapters/shared/mssql.rb +132 -72
- data/lib/sequel/adapters/shared/mysql.rb +112 -65
- data/lib/sequel/adapters/shared/oracle.rb +36 -21
- data/lib/sequel/adapters/shared/postgres.rb +91 -56
- data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
- data/lib/sequel/adapters/shared/sqlite.rb +67 -32
- data/lib/sequel/adapters/sqlanywhere.rb +9 -1
- data/lib/sequel/adapters/sqlite.rb +8 -1
- data/lib/sequel/adapters/swift.rb +5 -0
- data/lib/sequel/adapters/swift/mysql.rb +4 -2
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +10 -3
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
- data/lib/sequel/adapters/utils/pg_types.rb +14 -6
- data/lib/sequel/adapters/utils/replace.rb +4 -2
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/core.rb +24 -11
- data/lib/sequel/database/connecting.rb +9 -3
- data/lib/sequel/database/dataset_defaults.rb +7 -1
- data/lib/sequel/database/logging.rb +1 -0
- data/lib/sequel/database/misc.rb +5 -2
- data/lib/sequel/database/query.rb +7 -5
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +50 -27
- data/lib/sequel/database/transactions.rb +19 -9
- data/lib/sequel/dataset/actions.rb +15 -6
- data/lib/sequel/dataset/graph.rb +15 -5
- data/lib/sequel/dataset/misc.rb +12 -4
- data/lib/sequel/dataset/mutation.rb +17 -8
- data/lib/sequel/dataset/prepared_statements.rb +3 -2
- data/lib/sequel/dataset/query.rb +84 -38
- data/lib/sequel/dataset/sql.rb +302 -191
- data/lib/sequel/deprecated.rb +26 -17
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/from_block.rb +1 -0
- data/lib/sequel/extensions/graph_each.rb +1 -1
- data/lib/sequel/extensions/identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/migration.rb +28 -4
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +4 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
- data/lib/sequel/extensions/set_overrides.rb +2 -0
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +11 -7
- data/lib/sequel/model/associations.rb +5 -7
- data/lib/sequel/model/base.rb +47 -45
- data/lib/sequel/model/dataset_module.rb +9 -14
- data/lib/sequel/model/plugins.rb +3 -0
- data/lib/sequel/no_core_ext.rb +1 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -1
- data/lib/sequel/plugins/boolean_subsets.rb +7 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
- data/lib/sequel/plugins/dataset_associations.rb +1 -1
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/finder.rb +240 -0
- data/lib/sequel/plugins/inverted_subsets.rb +19 -12
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/schema.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
- data/lib/sequel/plugins/subset_conditions.rb +11 -3
- data/lib/sequel/plugins/whitelist_security.rb +118 -0
- data/lib/sequel/sql.rb +80 -36
- data/lib/sequel/timezones.rb +2 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +20 -0
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +12 -8
- data/spec/adapters/postgres_spec.rb +1 -1
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +36 -34
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +87 -9
- data/spec/core/dataset_spec.rb +501 -129
- data/spec/core/deprecated_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +146 -60
- data/spec/core/mock_adapter_spec.rb +1 -1
- data/spec/core/object_graph_spec.rb +61 -9
- data/spec/core/placeholder_literalizer_spec.rb +20 -2
- data/spec/core/schema_generator_spec.rb +6 -6
- data/spec/core/schema_spec.rb +54 -5
- data/spec/core_extensions_spec.rb +122 -18
- data/spec/deprecation_helper.rb +27 -2
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
- data/spec/extensions/association_proxies_spec.rb +2 -2
- data/spec/extensions/auto_literal_strings_spec.rb +212 -0
- data/spec/extensions/blacklist_security_spec.rb +1 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
- data/spec/extensions/column_select_spec.rb +20 -8
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/core_refinements_spec.rb +29 -12
- data/spec/extensions/dataset_associations_spec.rb +12 -12
- data/spec/extensions/def_dataset_method_spec.rb +100 -0
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +260 -0
- data/spec/extensions/graph_each_spec.rb +2 -2
- data/spec/extensions/identifier_mangling_spec.rb +14 -8
- data/spec/extensions/inverted_subsets_spec.rb +4 -4
- data/spec/extensions/lazy_attributes_spec.rb +7 -0
- data/spec/extensions/many_through_many_spec.rb +38 -14
- data/spec/extensions/nested_attributes_spec.rb +18 -6
- data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
- data/spec/extensions/pg_enum_spec.rb +16 -1
- data/spec/extensions/pg_interval_spec.rb +11 -2
- data/spec/extensions/pg_loose_count_spec.rb +5 -0
- data/spec/extensions/pg_row_spec.rb +25 -0
- data/spec/extensions/prepared_statements_spec.rb +10 -1
- data/spec/extensions/query_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/set_overrides_spec.rb +7 -3
- data/spec/extensions/sql_expr_spec.rb +0 -1
- data/spec/extensions/subset_conditions_spec.rb +6 -6
- data/spec/extensions/table_select_spec.rb +24 -12
- data/spec/extensions/to_dot_spec.rb +4 -4
- data/spec/extensions/whitelist_security_spec.rb +131 -0
- data/spec/integration/dataset_test.rb +9 -5
- data/spec/integration/model_test.rb +2 -0
- data/spec/integration/plugin_test.rb +2 -2
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/model/associations_spec.rb +39 -11
- data/spec/model/base_spec.rb +44 -24
- data/spec/model/class_dataset_methods_spec.rb +18 -16
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +84 -24
- data/spec/model/model_spec.rb +97 -63
- data/spec/model/record_spec.rb +21 -13
- metadata +13 -2
|
@@ -38,7 +38,7 @@ describe Sequel::Dataset, " graphing" do
|
|
|
38
38
|
|
|
39
39
|
@ds1.graph(@ds2, :x=>:id).all.must_equal [{:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}}]
|
|
40
40
|
@ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id).all.must_equal [{:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12}}]
|
|
41
|
-
@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y
|
|
41
|
+
@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>Sequel[:points][:id]}, :table_alias=>:graph).all.must_equal [{:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graph=>{:id=>8, :x=>9, :y=>10, :graph_id=>11}}]
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it "#graph_each should split the result set into component tables when using first" do
|
|
@@ -48,7 +48,7 @@ describe Sequel::Dataset, " graphing" do
|
|
|
48
48
|
|
|
49
49
|
@ds1.graph(@ds2, :x=>:id).first.must_equal(:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7})
|
|
50
50
|
@ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id).first.must_equal(:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12})
|
|
51
|
-
@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y
|
|
51
|
+
@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>Sequel[:points][:id]}, :table_alias=>:graph).first.must_equal(:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graph=>{:id=>8, :x=>9, :y=>10, :graph_id=>11})
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
it "#graph_each should give a nil value instead of a hash when all values for a table are nil" do
|
|
@@ -24,7 +24,8 @@ describe "identifier_mangling extension" do
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it "should upcase on input and downcase on output by default" do
|
|
27
|
-
|
|
27
|
+
# SEQUEL5: Remove :identifier_mangling=>false
|
|
28
|
+
db = Sequel::Database.new(:identifier_mangling=>false).extension(:identifier_mangling)
|
|
28
29
|
db.send(:identifier_input_method_default).must_equal :upcase
|
|
29
30
|
db.send(:identifier_output_method_default).must_equal :downcase
|
|
30
31
|
end
|
|
@@ -141,9 +142,9 @@ describe "identifier_mangling extension" do
|
|
|
141
142
|
deprecated "should respect the quote_indentifiers_default method if Sequel.quote_identifiers = nil" do
|
|
142
143
|
Sequel.quote_identifiers = nil
|
|
143
144
|
Sequel::Database.new.extension(:identifier_mangling).quote_identifiers?.must_equal true
|
|
144
|
-
x = Class.new(Sequel::Database){def quote_identifiers_default; false end}
|
|
145
|
+
x = Class.new(Sequel::Database){def dataset_class_default; Sequel::Dataset end; def quote_identifiers_default; false end}
|
|
145
146
|
x.new.extension(:identifier_mangling).quote_identifiers?.must_equal false
|
|
146
|
-
y = Class.new(Sequel::Database){def quote_identifiers_default; true end}
|
|
147
|
+
y = Class.new(Sequel::Database){def dataset_class_default; Sequel::Dataset end; def quote_identifiers_default; true end}
|
|
147
148
|
y.new.extension(:identifier_mangling).quote_identifiers?.must_equal true
|
|
148
149
|
end
|
|
149
150
|
|
|
@@ -151,9 +152,9 @@ describe "identifier_mangling extension" do
|
|
|
151
152
|
class Sequel::Database
|
|
152
153
|
@identifier_input_method = nil
|
|
153
154
|
end
|
|
154
|
-
x = Class.new(Sequel::Database){def identifier_input_method_default; :downcase end}
|
|
155
|
+
x = Class.new(Sequel::Database){def dataset_class_default; Sequel::Dataset end; def identifier_input_method_default; :downcase end}
|
|
155
156
|
x.new.extension(:identifier_mangling).identifier_input_method.must_equal :downcase
|
|
156
|
-
y = Class.new(Sequel::Database){def identifier_input_method_default; :camelize end}
|
|
157
|
+
y = Class.new(Sequel::Database){def dataset_class_default; Sequel::Dataset end; def identifier_input_method_default; :camelize end}
|
|
157
158
|
y.new.extension(:identifier_mangling).identifier_input_method.must_equal :camelize
|
|
158
159
|
end
|
|
159
160
|
|
|
@@ -161,9 +162,9 @@ describe "identifier_mangling extension" do
|
|
|
161
162
|
class Sequel::Database
|
|
162
163
|
@identifier_output_method = nil
|
|
163
164
|
end
|
|
164
|
-
x = Class.new(Sequel::Database){def identifier_output_method_default; :upcase end}
|
|
165
|
+
x = Class.new(Sequel::Database){def dataset_class_default; Sequel::Dataset end; def identifier_output_method_default; :upcase end}
|
|
165
166
|
x.new.extension(:identifier_mangling).identifier_output_method.must_equal :upcase
|
|
166
|
-
y = Class.new(Sequel::Database){def identifier_output_method_default; :underscore end}
|
|
167
|
+
y = Class.new(Sequel::Database){def dataset_class_default; Sequel::Dataset end; def identifier_output_method_default; :underscore end}
|
|
167
168
|
y.new.extension(:identifier_mangling).identifier_output_method.must_equal :underscore
|
|
168
169
|
end
|
|
169
170
|
end
|
|
@@ -315,7 +316,7 @@ describe "identifier_mangling extension" do
|
|
|
315
316
|
Sequel.mock(:host=>'oracle')[:a].limit(1).sql.must_equal 'SELECT * FROM (SELECT * FROM "A") "T1" WHERE (ROWNUM <= 1)'
|
|
316
317
|
Sequel.mock(:host=>'postgres')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM \"a\" WHERE (to_tsvector(CAST('simple' AS regconfig), (COALESCE(\"b\", ''))) @@ to_tsquery(CAST('simple' AS regconfig), 'c'))"
|
|
317
318
|
Sequel.mock(:host=>'sqlanywhere').from(:a).offset(1).sql.must_equal 'SELECT TOP 2147483647 START AT (1 + 1) * FROM "A"'
|
|
318
|
-
Sequel.mock(:host=>'sqlite')[:
|
|
319
|
+
Sequel.mock(:host=>'sqlite')[Sequel[:a].as(:b)].sql.must_equal "SELECT * FROM `a` AS 'b'"
|
|
319
320
|
ensure
|
|
320
321
|
deprecated do
|
|
321
322
|
Sequel.quote_identifiers = qi
|
|
@@ -341,7 +342,12 @@ describe Sequel::Model, ".[] optimization" do
|
|
|
341
342
|
@c.simple_table.must_equal '"ba"'
|
|
342
343
|
@c.set_primary_key :cd
|
|
343
344
|
@c.simple_pk.must_equal '"dc"'
|
|
345
|
+
@c.set_dataset ds.from(Sequel[:ef][:gh])
|
|
346
|
+
@c.simple_table.must_equal '"fe"."hg"'
|
|
347
|
+
end
|
|
344
348
|
|
|
349
|
+
with_symbol_splitting "should have simple_pk and simple_table respect dataset's identifier input methods when using splittable symbols" do
|
|
350
|
+
ds = @db.from(:ab).with_identifier_input_method(:reverse)
|
|
345
351
|
@c.set_dataset ds.from(:ef__gh)
|
|
346
352
|
@c.simple_table.must_equal '"fe"."hg"'
|
|
347
353
|
end
|
|
@@ -4,21 +4,21 @@ describe "Sequel::Plugins::InvertedSubsets" do
|
|
|
4
4
|
it "should add an inverted subset method which inverts the condition" do
|
|
5
5
|
c = Class.new(Sequel::Model(:a))
|
|
6
6
|
c.plugin :inverted_subsets
|
|
7
|
-
c.subset(:published, :published => true)
|
|
7
|
+
c.dataset_module{subset(:published, :published => true)}
|
|
8
8
|
c.not_published.sql.must_equal 'SELECT * FROM a WHERE (published IS NOT TRUE)'
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it "should support a configuration block to customise the inverted method name" do
|
|
12
12
|
c = Class.new(Sequel::Model(:a))
|
|
13
13
|
c.plugin(:inverted_subsets){|name| "exclude_#{name}"}
|
|
14
|
-
c.
|
|
14
|
+
c.dataset_module{where(:published, :published => true)}
|
|
15
15
|
c.exclude_published.sql.must_equal 'SELECT * FROM a WHERE (published IS NOT TRUE)'
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "should chain to existing dataset" do
|
|
19
19
|
c = Class.new(Sequel::Model(:a))
|
|
20
20
|
c.plugin :inverted_subsets
|
|
21
|
-
c.
|
|
21
|
+
c.dataset_module{where(:published, :published => true)}
|
|
22
22
|
c.where(1=>0).not_published.sql.must_equal 'SELECT * FROM a WHERE ((1 = 0) AND (published IS NOT TRUE))'
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ describe "Sequel::Plugins::InvertedSubsets" do
|
|
|
27
27
|
c.plugin(:inverted_subsets){|name| "exclude_#{name}"}
|
|
28
28
|
c = Class.new(c)
|
|
29
29
|
c.dataset = :a
|
|
30
|
-
c.subset(:published, :published => true)
|
|
30
|
+
c.dataset_module{subset(:published, :published => true)}
|
|
31
31
|
c.exclude_published.sql.must_equal 'SELECT * FROM a WHERE (published IS NOT TRUE)'
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -63,6 +63,13 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
it "should handle lazy attributes that are qualified in the selection" do
|
|
66
|
+
@c.set_dataset(@ds.select(Sequel[:la][:id], Sequel[:la][:blah]))
|
|
67
|
+
@c.dataset.sql.must_equal 'SELECT la.id, la.blah FROM la'
|
|
68
|
+
@c.plugin :lazy_attributes, :blah
|
|
69
|
+
@c.dataset.sql.must_equal 'SELECT la.id FROM la'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
with_symbol_splitting "should handle lazy attributes that are qualified in the selection using symbol splitting" do
|
|
66
73
|
@c.set_dataset(@ds.select(:la__id, :la__blah))
|
|
67
74
|
@c.dataset.sql.must_equal 'SELECT la.id, la.blah FROM la'
|
|
68
75
|
@c.plugin :lazy_attributes, :blah
|
|
@@ -62,7 +62,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
62
62
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
|
|
63
63
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
64
64
|
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
65
|
-
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel
|
|
65
|
+
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>(Sequel[:albums_artists][:artist_id] / 3)
|
|
66
66
|
a = @c1.eager(:tags).all
|
|
67
67
|
a.must_equal [@c1.load(:id => 1)]
|
|
68
68
|
DB.sqls.must_equal ['SELECT * FROM artists', "SELECT tags.*, (albums_artists.artist_id / 3) AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id / 3) IN (1))"]
|
|
@@ -70,6 +70,20 @@ describe Sequel::Model, "many_through_many" do
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
it "should handle schema qualified tables" do
|
|
73
|
+
@c1.many_through_many :tags, :through=>[[Sequel[:myschema][:albums_artists], :artist_id, :album_id], [Sequel[:myschema][:albums], :id, :id], [Sequel[:myschema][:albums_tags], :album_id, :tag_id]]
|
|
74
|
+
@c1.load(:id=>1).tags_dataset.sql.must_equal "SELECT tags.* FROM tags INNER JOIN myschema.albums_tags ON (myschema.albums_tags.tag_id = tags.id) INNER JOIN myschema.albums ON (myschema.albums.id = myschema.albums_tags.album_id) INNER JOIN myschema.albums_artists ON (myschema.albums_artists.album_id = myschema.albums.id) WHERE (myschema.albums_artists.artist_id = 1)"
|
|
75
|
+
|
|
76
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
77
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
78
|
+
a = @c1.eager(:tags).all
|
|
79
|
+
a.must_equal [@c1.load(:id => 1)]
|
|
80
|
+
DB.sqls.must_equal ['SELECT * FROM artists', "SELECT tags.*, myschema.albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN myschema.albums_tags ON (myschema.albums_tags.tag_id = tags.id) INNER JOIN myschema.albums ON (myschema.albums.id = myschema.albums_tags.album_id) INNER JOIN myschema.albums_artists ON (myschema.albums_artists.album_id = myschema.albums.id) WHERE (myschema.albums_artists.artist_id IN (1))"]
|
|
81
|
+
|
|
82
|
+
Tag.dataset.columns(:id, :h1, :h2)
|
|
83
|
+
@c1.eager_graph(:tags).sql.must_equal 'SELECT artists.id, tags.id AS tags_id, tags.h1, tags.h2 FROM artists LEFT OUTER JOIN myschema.albums_artists AS albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN myschema.albums AS albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN myschema.albums_tags AS albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
with_symbol_splitting "should handle schema qualified table symbols" do
|
|
73
87
|
@c1.many_through_many :tags, :through=>[[:myschema__albums_artists, :artist_id, :album_id], [:myschema__albums, :id, :id], [:myschema__albums_tags, :album_id, :tag_id]]
|
|
74
88
|
@c1.load(:id=>1).tags_dataset.sql.must_equal "SELECT tags.* FROM tags INNER JOIN myschema.albums_tags ON (myschema.albums_tags.tag_id = tags.id) INNER JOIN myschema.albums ON (myschema.albums.id = myschema.albums_tags.album_id) INNER JOIN myschema.albums_artists ON (myschema.albums_artists.album_id = myschema.albums.id) WHERE (myschema.albums_artists.artist_id = 1)"
|
|
75
89
|
|
|
@@ -335,7 +349,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
335
349
|
n.tags_dataset.sql.must_equal 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((a = 32) AND (albums_artists.artist_id = 1234))'
|
|
336
350
|
n.tags.must_equal [@c2.load(:id=>1)]
|
|
337
351
|
|
|
338
|
-
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>
|
|
352
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>Sequel.lit('a = ?', 42)
|
|
339
353
|
n = @c1.load(:id => 1234)
|
|
340
354
|
n.tags_dataset.sql.must_equal 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((a = 42) AND (albums_artists.artist_id = 1234))'
|
|
341
355
|
n.tags.must_equal [@c2.load(:id=>1)]
|
|
@@ -363,7 +377,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
363
377
|
end
|
|
364
378
|
|
|
365
379
|
it "should support an array for the select option" do
|
|
366
|
-
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), :
|
|
380
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), Sequel[:albums][:name]]
|
|
367
381
|
n = @c1.load(:id => 1234)
|
|
368
382
|
n.tags_dataset.sql.must_equal 'SELECT tags.*, albums.name FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234)'
|
|
369
383
|
n.tags.must_equal [@c2.load(:id=>1)]
|
|
@@ -386,7 +400,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
386
400
|
end
|
|
387
401
|
|
|
388
402
|
it "should support a :dataset option that is used instead of the default" do
|
|
389
|
-
@c1.many_through_many :tags, [[:a, :b, :c]], :dataset=>proc{Tag.join(:albums_tags, [:tag_id]).join(:albums, [:album_id]).join(:albums_artists, [:album_id]).filter(:
|
|
403
|
+
@c1.many_through_many :tags, [[:a, :b, :c]], :dataset=>proc{Tag.join(:albums_tags, [:tag_id]).join(:albums, [:album_id]).join(:albums_artists, [:album_id]).filter(Sequel[:albums_artists][:artist_id]=>id)}
|
|
390
404
|
n = @c1.load(:id => 1234)
|
|
391
405
|
n.tags_dataset.sql.must_equal 'SELECT tags.* FROM tags INNER JOIN albums_tags USING (tag_id) INNER JOIN albums USING (album_id) INNER JOIN albums_artists USING (album_id) WHERE (albums_artists.artist_id = 1234)'
|
|
392
406
|
n.tags.must_equal [@c2.load(:id=>1)]
|
|
@@ -839,7 +853,7 @@ describe "many_through_many eager loading methods" do
|
|
|
839
853
|
end
|
|
840
854
|
|
|
841
855
|
it "should respect the association's :select option" do
|
|
842
|
-
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select
|
|
856
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>Sequel[:tags][:name]
|
|
843
857
|
a = @c1.eager(:tags).all
|
|
844
858
|
a.must_equal [@c1.load(:id=>1)]
|
|
845
859
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -1103,17 +1117,22 @@ describe "many_through_many eager loading methods" do
|
|
|
1103
1117
|
|
|
1104
1118
|
it "should respect the association's :order" do
|
|
1105
1119
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
|
|
1106
|
-
@c1.order(:
|
|
1120
|
+
@c1.order(Sequel[:artists][:blah2], Sequel[:artists][:blah3]).eager_graph(:tags).sql.must_equal 'SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tags.blah1, tags.blah2'
|
|
1107
1121
|
end
|
|
1108
1122
|
|
|
1109
|
-
|
|
1123
|
+
with_symbol_splitting "should not qualify qualified symbols" do
|
|
1110
1124
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(:blah__id), :blah__id, :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
|
1111
1125
|
@c1.order(:artists__blah2, :artists__blah3).eager_graph(:tags).sql.must_equal 'SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tags.blah__id, tags.blah__id DESC, blah.id DESC, blah.id, tags.album_id, tags.album_id DESC, 1, RANDOM(), b.a'
|
|
1112
1126
|
end
|
|
1113
1127
|
|
|
1128
|
+
it "should only qualify symbols, identifiers, or ordered versions in association's :order" do
|
|
1129
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(Sequel[:blah][:id]), Sequel[:blah][:id], :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
|
1130
|
+
@c1.order(Sequel[:artists][:blah2], Sequel[:artists][:blah3]).eager_graph(:tags).sql.must_equal 'SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tags.blah__id, tags.blah__id DESC, blah.id DESC, blah.id, tags.album_id, tags.album_id DESC, 1, RANDOM(), b.a'
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1114
1133
|
it "should not respect the association's :order if :order_eager_graph is false" do
|
|
1115
1134
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2], :order_eager_graph=>false
|
|
1116
|
-
@c1.order(:
|
|
1135
|
+
@c1.order(Sequel[:artists][:blah2], Sequel[:artists][:blah3]).eager_graph(:tags).sql.must_equal 'SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3'
|
|
1117
1136
|
end
|
|
1118
1137
|
|
|
1119
1138
|
it "should add the associations :order for multiple associations" do
|
|
@@ -1215,7 +1234,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1215
1234
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
|
|
1216
1235
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
1217
1236
|
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
1218
|
-
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel
|
|
1237
|
+
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>(Sequel[:albums_artists][:artist_id] / 3)
|
|
1219
1238
|
a = @c1.eager(:tag).all
|
|
1220
1239
|
a.must_equal [@c1.load(:id => 1)]
|
|
1221
1240
|
DB.sqls.must_equal ['SELECT * FROM artists', "SELECT tags.*, (albums_artists.artist_id / 3) AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id / 3) IN (1))"]
|
|
@@ -1458,7 +1477,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1458
1477
|
n.tag_dataset.sql.must_equal 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((a = 32) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
|
1459
1478
|
n.tag.must_equal @c2.load(:id=>1)
|
|
1460
1479
|
|
|
1461
|
-
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>
|
|
1480
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>Sequel.lit('a = ?', 42)
|
|
1462
1481
|
n = @c1.load(:id => 1234)
|
|
1463
1482
|
n.tag_dataset.sql.must_equal 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((a = 42) AND (albums_artists.artist_id = 1234)) LIMIT 1'
|
|
1464
1483
|
n.tag.must_equal @c2.load(:id=>1)
|
|
@@ -1486,7 +1505,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1486
1505
|
end
|
|
1487
1506
|
|
|
1488
1507
|
it "should support an array for the select option" do
|
|
1489
|
-
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), :
|
|
1508
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), Sequel[:albums][:name]]
|
|
1490
1509
|
n = @c1.load(:id => 1234)
|
|
1491
1510
|
n.tag_dataset.sql.must_equal 'SELECT tags.*, albums.name FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
|
|
1492
1511
|
n.tag.must_equal @c2.load(:id=>1)
|
|
@@ -1509,7 +1528,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1509
1528
|
end
|
|
1510
1529
|
|
|
1511
1530
|
it "should support a :dataset option that is used instead of the default" do
|
|
1512
|
-
@c1.one_through_many :tag, [[:a, :b, :c]], :dataset=>proc{Tag.join(:albums_tags, [:tag_id]).join(:albums, [:album_id]).join(:albums_artists, [:album_id]).filter(:
|
|
1531
|
+
@c1.one_through_many :tag, [[:a, :b, :c]], :dataset=>proc{Tag.join(:albums_tags, [:tag_id]).join(:albums, [:album_id]).join(:albums_artists, [:album_id]).filter(Sequel[:albums_artists][:artist_id]=>id)}
|
|
1513
1532
|
n = @c1.load(:id => 1234)
|
|
1514
1533
|
n.tag_dataset.sql.must_equal 'SELECT tags.* FROM tags INNER JOIN albums_tags USING (tag_id) INNER JOIN albums USING (album_id) INNER JOIN albums_artists USING (album_id) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
|
|
1515
1534
|
n.tag.must_equal @c2.load(:id=>1)
|
|
@@ -1856,7 +1875,7 @@ describe "one_through_many eager loading methods" do
|
|
|
1856
1875
|
end
|
|
1857
1876
|
|
|
1858
1877
|
it "should respect the association's :select option" do
|
|
1859
|
-
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select
|
|
1878
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>Sequel[:tags][:name]
|
|
1860
1879
|
a = @c1.eager(:tag).all
|
|
1861
1880
|
a.must_equal [@c1.load(:id=>1)]
|
|
1862
1881
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -2107,10 +2126,15 @@ describe "one_through_many eager loading methods" do
|
|
|
2107
2126
|
|
|
2108
2127
|
it "should respect the association's :order" do
|
|
2109
2128
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
|
|
2110
|
-
@c1.order(:
|
|
2129
|
+
@c1.order(Sequel[:artists][:blah2], Sequel[:artists][:blah3]).eager_graph(:tag).sql.must_equal 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tag.blah1, tag.blah2'
|
|
2111
2130
|
end
|
|
2112
2131
|
|
|
2113
2132
|
it "should only qualify unqualified symbols, identifiers, or ordered versions in association's :order" do
|
|
2133
|
+
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(Sequel[:blah][:id]), Sequel[:blah][:id], :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
|
2134
|
+
@c1.order(Sequel[:artists][:blah2], Sequel[:artists][:blah3]).eager_graph(:tag).sql.must_equal 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tag.blah__id, tag.blah__id DESC, blah.id DESC, blah.id, tag.album_id, tag.album_id DESC, 1, RANDOM(), b.a'
|
|
2135
|
+
end
|
|
2136
|
+
|
|
2137
|
+
with_symbol_splitting "should not qualify qualified symbols in association's :order" do
|
|
2114
2138
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(:blah__id), :blah__id, :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
|
2115
2139
|
@c1.order(:artists__blah2, :artists__blah3).eager_graph(:tag).sql.must_equal 'SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) ORDER BY artists.blah2, artists.blah3, tag.blah__id, tag.blah__id DESC, blah.id DESC, blah.id, tag.album_id, tag.album_id DESC, 1, RANDOM(), b.a'
|
|
2116
2140
|
end
|
|
@@ -652,8 +652,12 @@ describe "NestedAttributes plugin" do
|
|
|
652
652
|
"UPDATE tags SET name = 'T2' WHERE (id = 30)",
|
|
653
653
|
"INSERT INTO tags (name) VALUES ('T3')",
|
|
654
654
|
["INSERT INTO at (album_id, tag_id) VALUES (10, 1)", "INSERT INTO at (tag_id, album_id) VALUES (1, 10)"])
|
|
655
|
-
|
|
656
|
-
|
|
655
|
+
al.set(:tags_attributes=>[{:id=>30, :name=>'T3', :number=>3}])
|
|
656
|
+
al.tags.first.name.must_equal 'T3'
|
|
657
|
+
al.tags.first.number.must_equal 10
|
|
658
|
+
al.set(:tags_attributes=>[{:name=>'T4', :number=>3}])
|
|
659
|
+
al.tags.last.name.must_equal 'T4'
|
|
660
|
+
al.tags.last.number.must_be_nil
|
|
657
661
|
end
|
|
658
662
|
|
|
659
663
|
it "should accept a proc for the :fields option that accepts the associated object and returns an array of fields" do
|
|
@@ -670,8 +674,12 @@ describe "NestedAttributes plugin" do
|
|
|
670
674
|
"UPDATE tags SET name = 'T2' WHERE (id = 30)",
|
|
671
675
|
"INSERT INTO tags (name) VALUES ('T3')",
|
|
672
676
|
["INSERT INTO at (album_id, tag_id) VALUES (10, 1)", "INSERT INTO at (tag_id, album_id) VALUES (1, 10)"])
|
|
673
|
-
|
|
674
|
-
|
|
677
|
+
al.set_nested_attributes(:tags, [{:id=>30, :name=>'T3', :number=>3}], :fields=>[:name])
|
|
678
|
+
al.tags.first.name.must_equal 'T3'
|
|
679
|
+
al.tags.first.number.must_equal 10
|
|
680
|
+
al.set_nested_attributes(:tags, [{:name=>'T4', :number=>3}], :fields=>[:name])
|
|
681
|
+
al.tags.last.name.must_equal 'T4'
|
|
682
|
+
al.tags.last.number.must_be_nil
|
|
675
683
|
end
|
|
676
684
|
|
|
677
685
|
it "should allow per-call options via the set_nested_attributes method" do
|
|
@@ -688,8 +696,12 @@ describe "NestedAttributes plugin" do
|
|
|
688
696
|
"UPDATE tags SET name = 'T2' WHERE (id = 30)",
|
|
689
697
|
"INSERT INTO tags (name) VALUES ('T3')",
|
|
690
698
|
["INSERT INTO at (album_id, tag_id) VALUES (10, 1)", "INSERT INTO at (tag_id, album_id) VALUES (1, 10)"])
|
|
691
|
-
|
|
692
|
-
|
|
699
|
+
al.set_nested_attributes(:tags, [{:id=>30, :name=>'T3', :number=>3}], :fields=>[:name])
|
|
700
|
+
al.tags.first.name.must_equal 'T3'
|
|
701
|
+
al.tags.first.number.must_equal 10
|
|
702
|
+
al.set_nested_attributes(:tags, [{:name=>'T4', :number=>3}], :fields=>[:name])
|
|
703
|
+
al.tags.last.name.must_equal 'T4'
|
|
704
|
+
al.tags.last.number.must_be_nil
|
|
693
705
|
end
|
|
694
706
|
|
|
695
707
|
it "should have set_nested_attributes method raise error if called with a bad association" do
|
|
@@ -38,7 +38,7 @@ describe "no_auto_literal_strings extension" do
|
|
|
38
38
|
"SELECT * FROM t WHERE (a) LIMIT 1"]
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
deprecated "should handle literal strings in arrays in filter methods" do
|
|
42
42
|
@ds.where([Sequel.lit("a")]).sql.must_equal 'SELECT * FROM t WHERE (a)'
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -33,6 +33,11 @@ describe "pg_enum extension" do
|
|
|
33
33
|
it "should support #create_enum method for adding a new enum" do
|
|
34
34
|
@db.create_enum(:foo, [:a, :b, :c])
|
|
35
35
|
@db.sqls.first.must_equal "CREATE TYPE foo AS ENUM ('a', 'b', 'c')"
|
|
36
|
+
@db.create_enum(Sequel[:sch][:foo], %w'a b c')
|
|
37
|
+
@db.sqls.first.must_equal "CREATE TYPE sch.foo AS ENUM ('a', 'b', 'c')"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
with_symbol_splitting "should support #create_enum method for adding a new enum with qualified symbol" do
|
|
36
41
|
@db.create_enum(:sch__foo, %w'a b c')
|
|
37
42
|
@db.sqls.first.must_equal "CREATE TYPE sch.foo AS ENUM ('a', 'b', 'c')"
|
|
38
43
|
end
|
|
@@ -40,12 +45,17 @@ describe "pg_enum extension" do
|
|
|
40
45
|
it "should support #drop_enum method for dropping an enum" do
|
|
41
46
|
@db.drop_enum(:foo)
|
|
42
47
|
@db.sqls.first.must_equal "DROP TYPE foo"
|
|
43
|
-
@db.drop_enum(:
|
|
48
|
+
@db.drop_enum(Sequel[:sch][:foo], :if_exists=>true)
|
|
44
49
|
@db.sqls.first.must_equal "DROP TYPE IF EXISTS sch.foo"
|
|
45
50
|
@db.drop_enum('foo', :cascade=>true)
|
|
46
51
|
@db.sqls.first.must_equal "DROP TYPE foo CASCADE"
|
|
47
52
|
end
|
|
48
53
|
|
|
54
|
+
with_symbol_splitting "should support #drop_enum method for dropping an enum with a splittable symbol" do
|
|
55
|
+
@db.drop_enum(:sch__foo, :if_exists=>true)
|
|
56
|
+
@db.sqls.first.must_equal "DROP TYPE IF EXISTS sch.foo"
|
|
57
|
+
end
|
|
58
|
+
|
|
49
59
|
it "should support #add_enum_value method for adding value to an existing enum" do
|
|
50
60
|
@db.add_enum_value(:foo, :a)
|
|
51
61
|
@db.sqls.first.must_equal "ALTER TYPE foo ADD VALUE 'a'"
|
|
@@ -57,6 +67,11 @@ describe "pg_enum extension" do
|
|
|
57
67
|
end
|
|
58
68
|
|
|
59
69
|
it "should support :after option for #add_enum_value method for adding value after an existing enum value" do
|
|
70
|
+
@db.add_enum_value(Sequel[:sch][:foo], :a, :after=>:b)
|
|
71
|
+
@db.sqls.first.must_equal "ALTER TYPE sch.foo ADD VALUE 'a' AFTER 'b'"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
with_symbol_splitting "should support :after option for #add_enum_value method for adding value after an existing enum value with splittable symbol" do
|
|
60
75
|
@db.add_enum_value(:sch__foo, :a, :after=>:b)
|
|
61
76
|
@db.sqls.first.must_equal "ALTER TYPE sch.foo ADD VALUE 'a' AFTER 'b'"
|
|
62
77
|
end
|
|
@@ -2,6 +2,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
begin
|
|
4
4
|
require 'active_support/duration'
|
|
5
|
+
begin
|
|
6
|
+
require 'active_support/gem_version'
|
|
7
|
+
rescue LoadError
|
|
8
|
+
end
|
|
5
9
|
rescue LoadError => exc
|
|
6
10
|
skip_warn "pg_interval plugin: can't load active_support/duration (#{exc.class}: #{exc})"
|
|
7
11
|
else
|
|
@@ -21,8 +25,13 @@ describe "pg_interval extension" do
|
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
it "should literalize ActiveSupport::Duration instances with repeated parts correctly" do
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
if defined?(ActiveSupport::VERSION::STRING) && ActiveSupport::VERSION::STRING >= '5.1'
|
|
29
|
+
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, 2], [:seconds, 1]])).must_equal "'1 seconds '::interval"
|
|
30
|
+
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, 2], [:seconds, 1], [:days, 1], [:days, 4]])).must_equal "'4 days 1 seconds '::interval"
|
|
31
|
+
else
|
|
32
|
+
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, 2], [:seconds, 1]])).must_equal "'3 seconds '::interval"
|
|
33
|
+
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, 2], [:seconds, 1], [:days, 1], [:days, 4]])).must_equal "'5 days 3 seconds '::interval"
|
|
34
|
+
end
|
|
26
35
|
end
|
|
27
36
|
|
|
28
37
|
it "should not affect literalization of custom objects" do
|
|
@@ -12,6 +12,11 @@ describe "pg_loose_count extension" do
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it "should support schema qualified tables" do
|
|
15
|
+
@db.loose_count(Sequel[:a][:b]).must_equal 1
|
|
16
|
+
@db.sqls.must_equal ["SELECT CAST(reltuples AS integer) AS v FROM pg_class WHERE (oid = CAST(CAST('a.b' AS regclass) AS oid)) LIMIT 1"]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
with_symbol_splitting "should support schema qualified table symbols" do
|
|
15
20
|
@db.loose_count(:a__b).must_equal 1
|
|
16
21
|
@db.sqls.must_equal ["SELECT CAST(reltuples AS integer) AS v FROM pg_class WHERE (oid = CAST(CAST('a.b' AS regclass) AS oid)) LIMIT 1"]
|
|
17
22
|
end
|
|
@@ -207,6 +207,31 @@ describe "pg_row extension" do
|
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
it "should allow registering row type parsers for schema qualify types" do
|
|
210
|
+
@db.conversion_procs[4] = p4 = proc{|s| s.to_i}
|
|
211
|
+
@db.conversion_procs[5] = p5 = proc{|s| s * 2}
|
|
212
|
+
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
|
213
|
+
@db.register_row_type(Sequel[:foo][:bar])
|
|
214
|
+
@db.sqls.must_equal ["SELECT pg_type.oid, typrelid, typarray FROM pg_type INNER JOIN pg_namespace ON ((pg_namespace.oid = pg_type.typnamespace) AND (pg_namespace.nspname = 'foo')) WHERE ((typtype = 'c') AND (typname = 'bar')) LIMIT 1",
|
|
215
|
+
"SELECT attname, (CASE pg_type.typbasetype WHEN 0 THEN atttypid ELSE pg_type.typbasetype END) AS atttypid FROM pg_attribute INNER JOIN pg_type ON (pg_type.oid = pg_attribute.atttypid) WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
|
216
|
+
p1 = @db.conversion_procs[1]
|
|
217
|
+
p1.columns.must_equal [:bar, :baz]
|
|
218
|
+
p1.column_oids.must_equal [4, 5]
|
|
219
|
+
p1.column_converters.must_equal [p4, p5]
|
|
220
|
+
p1.oid.must_equal 1
|
|
221
|
+
|
|
222
|
+
c = p1.converter
|
|
223
|
+
c.superclass.must_equal @m::HashRow
|
|
224
|
+
c.columns.must_equal [:bar, :baz]
|
|
225
|
+
c.db_type.must_equal Sequel[:foo][:bar]
|
|
226
|
+
p1.typecaster.must_equal c
|
|
227
|
+
|
|
228
|
+
p1.call('(1,b)').must_equal(:bar=>1, :baz=>'bb')
|
|
229
|
+
@db.typecast_value(:pg_row_foo__bar, %w'1 b').must_equal(:bar=>'1', :baz=>'b')
|
|
230
|
+
@db.typecast_value(:pg_row_foo__bar, :bar=>'1', :baz=>'b').must_equal(:bar=>'1', :baz=>'b')
|
|
231
|
+
@db.literal(p1.call('(1,b)')).must_equal "ROW(1, 'bb')::foo.bar"
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
with_symbol_splitting "should allow registering row type parsers for schema qualify type symbols" do
|
|
210
235
|
@db.conversion_procs[4] = p4 = proc{|s| s.to_i}
|
|
211
236
|
@db.conversion_procs[5] = p5 = proc{|s| s * 2}
|
|
212
237
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|