sequel 4.45.0 → 4.46.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -13,20 +13,29 @@ describe "prepared_statements plugin" do
|
|
13
13
|
@db.sqls
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
deprecated "should correctly lookup by primary key for joined dataset" do
|
17
17
|
@c.dataset = @c.dataset.from(:people, :people2)
|
18
18
|
@db.sqls
|
19
19
|
@c[1].must_equal @p
|
20
20
|
@db.sqls.must_equal ["SELECT * FROM people, people2 WHERE (people.id = 1) LIMIT 1 -- read_only"]
|
21
21
|
end
|
22
22
|
|
23
|
+
it "should correctly lookup by primary key for dataset using subquery" do
|
24
|
+
@c.dataset = @c.dataset.from(:people, :people2).from_self(:alias=>:people)
|
25
|
+
@db.sqls
|
26
|
+
@c[1].must_equal @p
|
27
|
+
@db.sqls.must_equal ["SELECT * FROM (SELECT * FROM people, people2) AS people WHERE (id = 1) LIMIT 1 -- read_only"]
|
28
|
+
end
|
29
|
+
|
23
30
|
it "should use prepared statements for pk lookups only if default is not optimized" do
|
24
31
|
@c.send(:use_prepared_statements_for_pk_lookup?).must_equal false
|
25
32
|
@c.set_primary_key [:id, :name]
|
26
33
|
@c.send(:use_prepared_statements_for_pk_lookup?).must_equal true
|
27
34
|
@c.set_primary_key :id
|
35
|
+
deprecated do
|
28
36
|
@c.dataset = @c.dataset.from(:people, :people2)
|
29
37
|
@c.send(:use_prepared_statements_for_pk_lookup?).must_equal false
|
38
|
+
end
|
30
39
|
@c.dataset = @db[:people].select(:id, :name, :i)
|
31
40
|
@c.send(:use_prepared_statements_for_pk_lookup?).must_equal true
|
32
41
|
end
|
@@ -31,7 +31,7 @@ describe "Dataset#query" do
|
|
31
31
|
|
32
32
|
it "should support #select" do
|
33
33
|
q = @d.query do
|
34
|
-
select :a, :
|
34
|
+
select :a, Sequel[:b].as(:mongo)
|
35
35
|
from :yyy
|
36
36
|
end
|
37
37
|
q.class.must_equal @d.class
|
@@ -91,7 +91,7 @@ describe "Dataset#query" do
|
|
91
91
|
unless Sequel.mock.dataset.frozen?
|
92
92
|
deprecated "should have an appropriate mutation method" do
|
93
93
|
@d.query! do
|
94
|
-
select :a, :
|
94
|
+
select :a, Sequel[:b].as(:mongo)
|
95
95
|
from :yyy
|
96
96
|
end
|
97
97
|
@d.sql.must_equal "SELECT a, b AS mongo FROM yyy"
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
2
2
|
|
3
|
-
describe "Sequel::Schema::
|
3
|
+
describe "Sequel::Schema::CreateTableGenerator dump methods" do
|
4
4
|
before do
|
5
5
|
@d = Sequel::Database.new.extension(:schema_dumper)
|
6
|
-
@g = Sequel::Schema::
|
6
|
+
@g = Sequel::Schema::CreateTableGenerator
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should allow the same table information to be converted to a string for evaling inside of another instance with the same result" do
|
@@ -60,12 +60,12 @@ describe Sequel::Model, "create_table and schema" do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should return the schema generator via schema" do
|
63
|
-
@model.schema.must_be_kind_of(Sequel::Schema::
|
63
|
+
@model.schema.must_be_kind_of(Sequel::Schema::CreateTableGenerator)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should use the superclasses schema if it exists" do
|
67
67
|
@submodel = Class.new(@model)
|
68
|
-
@submodel.schema.must_be_kind_of(Sequel::Schema::
|
68
|
+
@submodel.schema.must_be_kind_of(Sequel::Schema::CreateTableGenerator)
|
69
69
|
end
|
70
70
|
|
71
71
|
it "should return nil if no schema is present" do
|
@@ -2,7 +2,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe "Sequel::Dataset #set_defaults" do
|
4
4
|
before do
|
5
|
-
|
5
|
+
deprecated do
|
6
|
+
@ds = Sequel.mock.dataset.from(:items).extension(:set_overrides).set_defaults(:x=>1)
|
7
|
+
end
|
6
8
|
end
|
7
9
|
|
8
10
|
it "should set the default values for inserts" do
|
@@ -21,7 +23,7 @@ describe "Sequel::Dataset #set_defaults" do
|
|
21
23
|
@ds.set_defaults(:x=>2).update_sql.must_equal "UPDATE items SET x = 2"
|
22
24
|
end
|
23
25
|
|
24
|
-
|
26
|
+
deprecated "should not affect String update arguments" do
|
25
27
|
@ds.update_sql('y = 2').must_equal "UPDATE items SET y = 2"
|
26
28
|
end
|
27
29
|
|
@@ -37,7 +39,9 @@ end
|
|
37
39
|
|
38
40
|
describe "Sequel::Dataset #set_overrides" do
|
39
41
|
before do
|
40
|
-
|
42
|
+
deprecated do
|
43
|
+
@ds = Sequel.mock.dataset.from(:items).extension(:set_overrides).set_overrides(:x=>1)
|
44
|
+
end
|
41
45
|
end
|
42
46
|
|
43
47
|
it "should override the given values for inserts" do
|
@@ -44,7 +44,6 @@ describe "Sequel sql_expr extension" do
|
|
44
44
|
|
45
45
|
it "Proc#sql_expr should should treat the object as a virtual row block" do
|
46
46
|
@ds.literal(proc{a}.sql_expr).must_equal "a"
|
47
|
-
@ds.literal(proc{a__b}.sql_expr).must_equal "a.b"
|
48
47
|
@ds.literal(proc{a(b)}.sql_expr).must_equal "a(b)"
|
49
48
|
end
|
50
49
|
|
@@ -7,13 +7,13 @@ describe "subset_conditions plugin" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should provide *_conditions method return the arguments passed" do
|
10
|
-
@c.subset(:published, :published => true)
|
10
|
+
@c.dataset_module{subset(:published, :published => true)}
|
11
11
|
@c.where(@c.published_conditions).sql.must_equal @c.published.sql
|
12
12
|
|
13
|
-
@c.
|
13
|
+
@c.dataset_module{where(:active, :active)}
|
14
14
|
@c.where(@c.active_conditions).sql.must_equal @c.active.sql
|
15
15
|
|
16
|
-
@c.subset(:active_published, Sequel.&(:active, :published => true))
|
16
|
+
@c.dataset_module{subset(:active_published, Sequel.&(:active, :published => true))}
|
17
17
|
@c.where(@c.active_published_conditions).sql.must_equal @c.active_published.sql
|
18
18
|
@c.where(Sequel.&(@c.active_conditions, @c.published_conditions)).sql.must_equal @c.active_published.sql
|
19
19
|
@c.where(Sequel.|(@c.active_conditions, @c.published_conditions)).sql.must_equal "SELECT * FROM a WHERE (active OR (published IS TRUE))"
|
@@ -22,14 +22,14 @@ describe "subset_conditions plugin" do
|
|
22
22
|
|
23
23
|
it "should work with blocks" do
|
24
24
|
p1 = proc{{:published=>true}}
|
25
|
-
@c.subset(:published, &p1)
|
25
|
+
@c.dataset_module{subset(:published, &p1)}
|
26
26
|
@c.where(@c.published_conditions).sql.must_equal @c.published.sql
|
27
27
|
|
28
28
|
p2 = :active
|
29
|
-
@c.subset(:active, p2)
|
29
|
+
@c.dataset_module{subset(:active, p2)}
|
30
30
|
@c.where(@c.active_conditions).sql.must_equal @c.active.sql
|
31
31
|
|
32
|
-
@c.subset(:active_published, p2, &p1)
|
32
|
+
@c.dataset_module{subset(:active_published, p2, &p1)}
|
33
33
|
@c.where(@c.active_published_conditions).sql.must_equal @c.active_published.sql
|
34
34
|
@c.where(Sequel.&(@c.active_conditions, @c.published_conditions)).sql.must_equal @c.active_published.sql
|
35
35
|
@c.where(Sequel.|(@c.active_conditions, @c.published_conditions)).sql.must_equal "SELECT * FROM a WHERE (active OR (published IS TRUE))"
|
@@ -17,25 +17,16 @@ describe "Sequel::Plugins::TableSelect" do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should handle qualified tables" do
|
20
|
-
@Album.dataset = :s__albums
|
21
|
-
@Album.plugin :table_select
|
22
|
-
@Album.dataset.sql.must_equal 'SELECT s.albums.* FROM s.albums'
|
23
|
-
|
24
20
|
@Album.dataset = Sequel.qualify(:s2, :albums)
|
21
|
+
@Album.plugin :table_select
|
25
22
|
@Album.dataset.sql.must_equal 'SELECT s2.albums.* FROM s2.albums'
|
26
23
|
end
|
27
24
|
|
28
25
|
it "should handle aliases" do
|
29
|
-
@Album.dataset = :albums___a
|
30
|
-
@Album.plugin :table_select
|
31
|
-
@Album.dataset.sql.must_equal 'SELECT a.* FROM albums AS a'
|
32
|
-
|
33
26
|
@Album.dataset = Sequel.as(:albums, :b)
|
27
|
+
@Album.plugin :table_select
|
34
28
|
@Album.dataset.sql.must_equal 'SELECT b.* FROM albums AS b'
|
35
29
|
|
36
|
-
@Album.dataset = :s__albums___a
|
37
|
-
@Album.dataset.sql.must_equal 'SELECT a.* FROM s.albums AS a'
|
38
|
-
|
39
30
|
@Album.dataset = @Album.db[:albums].from_self
|
40
31
|
@Album.dataset.sql.must_equal 'SELECT t1.* FROM (SELECT * FROM albums) AS t1'
|
41
32
|
|
@@ -43,6 +34,18 @@ describe "Sequel::Plugins::TableSelect" do
|
|
43
34
|
@Album.dataset.sql.must_equal 'SELECT b.* FROM (SELECT * FROM albums) AS b'
|
44
35
|
end
|
45
36
|
|
37
|
+
with_symbol_splitting "should handle splittable symbols" do
|
38
|
+
@Album.dataset = :albums___a
|
39
|
+
@Album.plugin :table_select
|
40
|
+
@Album.dataset.sql.must_equal 'SELECT a.* FROM albums AS a'
|
41
|
+
|
42
|
+
@Album.dataset = :s__albums___a
|
43
|
+
@Album.dataset.sql.must_equal 'SELECT a.* FROM s.albums AS a'
|
44
|
+
|
45
|
+
@Album.dataset = :s__albums
|
46
|
+
@Album.dataset.sql.must_equal 'SELECT s.albums.* FROM s.albums'
|
47
|
+
end
|
48
|
+
|
46
49
|
it "should not add a table.* selection on existing dataset with explicit selection" do
|
47
50
|
@Album.dataset = @Album.dataset.select(:name)
|
48
51
|
@Album.plugin :table_select
|
@@ -52,7 +55,16 @@ describe "Sequel::Plugins::TableSelect" do
|
|
52
55
|
@Album.dataset.sql.must_equal 'SELECT name, artist FROM albums'
|
53
56
|
end
|
54
57
|
|
55
|
-
it "should
|
58
|
+
it "should add a table.* selection on existing dataset with subquery" do
|
59
|
+
@Album.dataset = @Album.db.from(:a1, :a2).from_self(:alias=>:foo)
|
60
|
+
@Album.plugin :table_select
|
61
|
+
@Album.dataset.sql.must_equal 'SELECT foo.* FROM (SELECT * FROM a1, a2) AS foo'
|
62
|
+
|
63
|
+
@Album.dataset = @Album.db.from(:a1).cross_join(:a2).from_self(:alias=>:foo)
|
64
|
+
@Album.dataset.sql.must_equal 'SELECT foo.* FROM (SELECT * FROM a1 CROSS JOIN a2) AS foo'
|
65
|
+
end
|
66
|
+
|
67
|
+
deprecated "should not add a table.* selection on existing dataset with multiple tables" do
|
56
68
|
@Album.dataset = @Album.db.from(:a1, :a2)
|
57
69
|
@Album.plugin :table_select
|
58
70
|
@Album.dataset.sql.must_equal 'SELECT * FROM a1, a2'
|
@@ -80,7 +80,7 @@ END
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should handle LiteralStrings" do
|
83
|
-
dot(@ds.filter('a')).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"Sequel.lit(\\\"(a)\\\")\"];"]
|
83
|
+
dot(@ds.filter(Sequel.lit('a'))).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"Sequel.lit(\\\"(a)\\\")\"];"]
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should handle true, false, nil" do
|
@@ -96,7 +96,7 @@ END
|
|
96
96
|
end
|
97
97
|
|
98
98
|
it "should handle SQL::QualifiedIdentifiers" do
|
99
|
-
dot(@ds.select{
|
99
|
+
dot(@ds.select{a[b]}).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"QualifiedIdentifier\"];", "3 -> 4 [label=\"table\"];", "4 [label=\"\\\"a\\\"\"];", "3 -> 5 [label=\"column\"];", "5 [label=\"\\\"b\\\"\"];"]
|
100
100
|
end
|
101
101
|
|
102
102
|
it "should handle SQL::OrderedExpressions" do
|
@@ -128,11 +128,11 @@ END
|
|
128
128
|
end
|
129
129
|
|
130
130
|
it "should handle SQL::Function with a window" do
|
131
|
-
dot(@ds.select
|
131
|
+
dot(@ds.select(Sequel.function(:sum).over(:partition=>:a))).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Function: sum\"];", "3 -> 4 [label=\"args\"];", "4 [label=\"Array\"];", "3 -> 5 [label=\"opts\"];", "5 [label=\"Hash\"];", "5 -> 6 [label=\"over\"];", "6 [label=\"Window\"];", "6 -> 7 [label=\"opts\"];", "7 [label=\"Hash\"];", "7 -> 8 [label=\"partition\"];", "8 [label=\":a\"];"]
|
132
132
|
end
|
133
133
|
|
134
134
|
it "should handle SQL::PlaceholderLiteralString" do
|
135
|
-
dot(@ds.where("?", true)).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"PlaceholderLiteralString: \\\"(?)\\\"\"];", "2 -> 3 [label=\"args\"];", "3 [label=\"Array\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"true\"];"]
|
135
|
+
dot(@ds.where(Sequel.lit("?", true))).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"PlaceholderLiteralString: \\\"(?)\\\"\"];", "2 -> 3 [label=\"args\"];", "3 [label=\"Array\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"true\"];"]
|
136
136
|
end
|
137
137
|
|
138
138
|
it "should handle JOIN ON" do
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
describe Sequel::Model, "#(set|update)_(all|only)" do
|
4
|
+
before do
|
5
|
+
@c = Class.new(Sequel::Model(:items)) do
|
6
|
+
set_primary_key :id
|
7
|
+
columns :x, :y, :z, :id
|
8
|
+
end
|
9
|
+
@c.plugin :whitelist_security
|
10
|
+
@c.set_allowed_columns :x
|
11
|
+
@c.strict_param_setting = false
|
12
|
+
@o1 = @c.new
|
13
|
+
DB.reset
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should raise errors if not all hash fields can be set and strict_param_setting is true" do
|
17
|
+
@c.strict_param_setting = true
|
18
|
+
|
19
|
+
proc{@c.new.set_all(:x => 1, :y => 2, :z=>3, :use_after_commit_rollback => false)}.must_raise(Sequel::MassAssignmentRestriction)
|
20
|
+
(o = @c.new).set_all(:x => 1, :y => 2, :z=>3)
|
21
|
+
o.values.must_equal(:x => 1, :y => 2, :z=>3)
|
22
|
+
|
23
|
+
proc{@c.new.set_only({:x => 1, :y => 2, :z=>3, :id=>4}, :x, :y)}.must_raise(Sequel::MassAssignmentRestriction)
|
24
|
+
proc{@c.new.set_only({:x => 1, :y => 2, :z=>3}, :x, :y)}.must_raise(Sequel::MassAssignmentRestriction)
|
25
|
+
(o = @c.new).set_only({:x => 1, :y => 2}, :x, :y)
|
26
|
+
o.values.must_equal(:x => 1, :y => 2)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "#set_all should set all attributes including the primary key" do
|
30
|
+
@o1.set_all(:x => 1, :y => 2, :z=>3, :id=>4)
|
31
|
+
@o1.values.must_equal(:id =>4, :x => 1, :y => 2, :z=>3)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "#set_all should set not set restricted fields" do
|
35
|
+
@o1.use_after_commit_rollback.must_be_nil
|
36
|
+
@o1.set_all(:x => 1, :use_after_commit_rollback => true)
|
37
|
+
@o1.use_after_commit_rollback.must_be_nil
|
38
|
+
@o1.values.must_equal(:x => 1)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "#set_only should only set given attributes" do
|
42
|
+
@o1.set_only({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
|
43
|
+
@o1.values.must_equal(:x => 1, :y => 2)
|
44
|
+
@o1.set_only({:x => 4, :y => 5, :z=>6, :id=>7}, :x, :y)
|
45
|
+
@o1.values.must_equal(:x => 4, :y => 5)
|
46
|
+
@o1.set_only({:x => 9, :y => 8, :z=>6, :id=>7}, :x, :y, :id)
|
47
|
+
@o1.values.must_equal(:x => 9, :y => 8, :id=>7)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "#update_all should update all attributes" do
|
51
|
+
@c.new.update_all(:x => 1)
|
52
|
+
DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
|
53
|
+
@c.new.update_all(:y => 1)
|
54
|
+
DB.sqls.must_equal ["INSERT INTO items (y) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
|
55
|
+
@c.new.update_all(:z => 1)
|
56
|
+
DB.sqls.must_equal ["INSERT INTO items (z) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "#update_only should only update given attributes" do
|
60
|
+
@o1.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, [:x])
|
61
|
+
DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
|
62
|
+
@c.new.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, :x)
|
63
|
+
DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe Sequel::Model, ".strict_param_setting" do
|
68
|
+
before do
|
69
|
+
@c = Class.new(Sequel::Model(:blahblah)) do
|
70
|
+
columns :x, :y, :z, :id
|
71
|
+
end
|
72
|
+
@c.plugin :whitelist_security
|
73
|
+
@c.set_allowed_columns :x, :y
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise an error if a missing/restricted column/method is accessed" do
|
77
|
+
proc{@c.new(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
78
|
+
proc{@c.create(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
79
|
+
c = @c.new
|
80
|
+
proc{c.set(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
81
|
+
proc{c.update(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
82
|
+
proc{c.set_all(:use_after_commit_rollback => false)}.must_raise(Sequel::MassAssignmentRestriction)
|
83
|
+
proc{c.set_only({:x=>1}, :y)}.must_raise(Sequel::MassAssignmentRestriction)
|
84
|
+
proc{c.update_all(:use_after_commit_rollback=>false)}.must_raise(Sequel::MassAssignmentRestriction)
|
85
|
+
proc{c.update_only({:x=>1}, :y)}.must_raise(Sequel::MassAssignmentRestriction)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe Sequel::Model, ".allowed_columns " do
|
90
|
+
before do
|
91
|
+
@c = Class.new(Sequel::Model(:blahblah)) do
|
92
|
+
columns :x, :y, :z
|
93
|
+
end
|
94
|
+
@c.plugin :whitelist_security
|
95
|
+
@c.strict_param_setting = false
|
96
|
+
@c.instance_variable_set(:@columns, [:x, :y, :z])
|
97
|
+
DB.reset
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should set the allowed columns correctly" do
|
101
|
+
@c.allowed_columns.must_be_nil
|
102
|
+
@c.set_allowed_columns :x
|
103
|
+
@c.allowed_columns.must_equal [:x]
|
104
|
+
@c.set_allowed_columns :x, :y
|
105
|
+
@c.allowed_columns.must_equal [:x, :y]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should only set allowed columns by default" do
|
109
|
+
@c.set_allowed_columns :x, :y
|
110
|
+
i = @c.new(:x => 1, :y => 2, :z => 3)
|
111
|
+
i.values.must_equal(:x => 1, :y => 2)
|
112
|
+
i.set(:x => 4, :y => 5, :z => 6)
|
113
|
+
i.values.must_equal(:x => 4, :y => 5)
|
114
|
+
|
115
|
+
@c.dataset = @c.dataset.with_fetch(:x => 7)
|
116
|
+
i = @c.new
|
117
|
+
i.update(:x => 7, :z => 9)
|
118
|
+
i.values.must_equal(:x => 7)
|
119
|
+
DB.sqls.must_equal ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE id = 10"]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "Sequel::Model.freeze" do
|
124
|
+
it "should freeze the model class and not allow any changes" do
|
125
|
+
model = Class.new(Sequel::Model(:items))
|
126
|
+
model.plugin :whitelist_security
|
127
|
+
model.set_allowed_columns [:id]
|
128
|
+
model.freeze
|
129
|
+
model.allowed_columns.frozen?.must_equal true
|
130
|
+
end
|
131
|
+
end
|
@@ -866,9 +866,9 @@ if DB.dataset.supports_window_functions?
|
|
866
866
|
end
|
867
867
|
|
868
868
|
it "should give correct results for ranking window functions with orders" do
|
869
|
-
@ds.select(:id){rank
|
869
|
+
@ds.select(:id){rank.function.over(:partition=>:group_id, :order=>:id).as(:rank)}.all.
|
870
870
|
must_equal [{:rank=>1, :id=>1}, {:rank=>2, :id=>2}, {:rank=>3, :id=>3}, {:rank=>1, :id=>4}, {:rank=>2, :id=>5}, {:rank=>3, :id=>6}]
|
871
|
-
@ds.select(:id){rank
|
871
|
+
@ds.select(:id){rank.function.over(:order=>id).as(:rank)}.all.
|
872
872
|
must_equal [{:rank=>1, :id=>1}, {:rank=>2, :id=>2}, {:rank=>3, :id=>3}, {:rank=>4, :id=>4}, {:rank=>5, :id=>5}, {:rank=>6, :id=>6}]
|
873
873
|
end
|
874
874
|
|
@@ -1568,8 +1568,10 @@ describe "Dataset string methods" do
|
|
1568
1568
|
@db = DB
|
1569
1569
|
csc = {}
|
1570
1570
|
cic = {}
|
1571
|
-
|
1572
|
-
|
1571
|
+
if @db.database_type == :mssql
|
1572
|
+
csc[:collate] = 'Latin1_General_CS_AS'
|
1573
|
+
cic[:collate] = 'Latin1_General_CI_AS'
|
1574
|
+
end
|
1573
1575
|
@db.create_table!(:a) do
|
1574
1576
|
String :a, csc
|
1575
1577
|
String :b, cic
|
@@ -1752,7 +1754,9 @@ describe "Dataset defaults and overrides" do
|
|
1752
1754
|
before(:all) do
|
1753
1755
|
@db = DB
|
1754
1756
|
@db.create_table!(:a){Integer :a}
|
1755
|
-
|
1757
|
+
deprecated do
|
1758
|
+
@ds = @db[:a].order(:a).extension(:set_overrides)
|
1759
|
+
end
|
1756
1760
|
end
|
1757
1761
|
before do
|
1758
1762
|
@ds.delete
|
@@ -24,6 +24,7 @@ describe "Sequel::Model basic support" do
|
|
24
24
|
|
25
25
|
it ".finder should create method that returns first matching item" do
|
26
26
|
def Item.by_name(name) where(:name=>name) end
|
27
|
+
Item.plugin :finder
|
27
28
|
Item.finder :by_name
|
28
29
|
Item.first_by_name('J').must_be_nil
|
29
30
|
Item.create(:name=>'J')
|
@@ -33,6 +34,7 @@ describe "Sequel::Model basic support" do
|
|
33
34
|
|
34
35
|
it ".prepared_finder should create method that returns first matching item" do
|
35
36
|
def Item.by_name(name) where(:name=>name) end
|
37
|
+
Item.plugin :finder
|
36
38
|
Item.prepared_finder :by_name
|
37
39
|
Item.first_by_name('J').must_be_nil
|
38
40
|
Item.create(:name=>'J')
|
@@ -26,7 +26,7 @@ describe "Class Table Inheritance Plugin" do
|
|
26
26
|
before do
|
27
27
|
[:staff, :executives, :managers, :employees].each{|t| @db[t].delete}
|
28
28
|
class ::Employee < Sequel::Model(@db)
|
29
|
-
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
|
29
|
+
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}, :alias=>:employees
|
30
30
|
end
|
31
31
|
class ::Manager < Employee
|
32
32
|
one_to_many :staff_members, :class=>:Staff
|
@@ -166,7 +166,7 @@ describe "Class Table Inheritance Plugin" do
|
|
166
166
|
end
|
167
167
|
|
168
168
|
it "should handle eagerly graphing one_to_many relationships" do
|
169
|
-
es = Executive.where(:name=>'Ex').eager_graph(:staff_members).all
|
169
|
+
es = Executive.where(Sequel[:employees][:name]=>'Ex').eager_graph(:staff_members).all
|
170
170
|
es.must_equal [Executive[@i4]]
|
171
171
|
es.map{|x| x.staff_members}.must_equal [[Staff[@i2]]]
|
172
172
|
end
|