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
|
@@ -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
|