sequel 4.45.0 → 4.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +108 -0
  3. data/doc/release_notes/4.46.0.txt +404 -0
  4. data/doc/security.rdoc +9 -0
  5. data/doc/sql.rdoc +2 -2
  6. data/doc/testing.rdoc +1 -1
  7. data/doc/validations.rdoc +1 -2
  8. data/lib/sequel/adapters/ado.rb +8 -3
  9. data/lib/sequel/adapters/ado/access.rb +8 -4
  10. data/lib/sequel/adapters/ado/mssql.rb +3 -1
  11. data/lib/sequel/adapters/amalgalite.rb +5 -0
  12. data/lib/sequel/adapters/cubrid.rb +16 -7
  13. data/lib/sequel/adapters/do.rb +7 -1
  14. data/lib/sequel/adapters/do/mysql.rb +8 -4
  15. data/lib/sequel/adapters/ibmdb.rb +10 -5
  16. data/lib/sequel/adapters/jdbc.rb +8 -2
  17. data/lib/sequel/adapters/jdbc/as400.rb +10 -3
  18. data/lib/sequel/adapters/jdbc/db2.rb +27 -16
  19. data/lib/sequel/adapters/jdbc/derby.rb +47 -20
  20. data/lib/sequel/adapters/jdbc/h2.rb +13 -7
  21. data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
  22. data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
  23. data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
  24. data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
  25. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
  26. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
  27. data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
  28. data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
  29. data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
  30. data/lib/sequel/adapters/mock.rb +5 -0
  31. data/lib/sequel/adapters/mysql.rb +8 -1
  32. data/lib/sequel/adapters/mysql2.rb +6 -1
  33. data/lib/sequel/adapters/odbc.rb +20 -8
  34. data/lib/sequel/adapters/odbc/mssql.rb +6 -3
  35. data/lib/sequel/adapters/oracle.rb +12 -6
  36. data/lib/sequel/adapters/postgres.rb +20 -8
  37. data/lib/sequel/adapters/shared/access.rb +76 -47
  38. data/lib/sequel/adapters/shared/cubrid.rb +16 -11
  39. data/lib/sequel/adapters/shared/db2.rb +46 -19
  40. data/lib/sequel/adapters/shared/firebird.rb +20 -8
  41. data/lib/sequel/adapters/shared/informix.rb +6 -3
  42. data/lib/sequel/adapters/shared/mssql.rb +132 -72
  43. data/lib/sequel/adapters/shared/mysql.rb +112 -65
  44. data/lib/sequel/adapters/shared/oracle.rb +36 -21
  45. data/lib/sequel/adapters/shared/postgres.rb +91 -56
  46. data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
  47. data/lib/sequel/adapters/shared/sqlite.rb +67 -32
  48. data/lib/sequel/adapters/sqlanywhere.rb +9 -1
  49. data/lib/sequel/adapters/sqlite.rb +8 -1
  50. data/lib/sequel/adapters/swift.rb +5 -0
  51. data/lib/sequel/adapters/swift/mysql.rb +4 -2
  52. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  53. data/lib/sequel/adapters/tinytds.rb +10 -3
  54. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  55. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  56. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
  57. data/lib/sequel/adapters/utils/pg_types.rb +14 -6
  58. data/lib/sequel/adapters/utils/replace.rb +4 -2
  59. data/lib/sequel/connection_pool/single.rb +2 -2
  60. data/lib/sequel/core.rb +24 -11
  61. data/lib/sequel/database/connecting.rb +9 -3
  62. data/lib/sequel/database/dataset_defaults.rb +7 -1
  63. data/lib/sequel/database/logging.rb +1 -0
  64. data/lib/sequel/database/misc.rb +5 -2
  65. data/lib/sequel/database/query.rb +7 -5
  66. data/lib/sequel/database/schema_generator.rb +1 -0
  67. data/lib/sequel/database/schema_methods.rb +50 -27
  68. data/lib/sequel/database/transactions.rb +19 -9
  69. data/lib/sequel/dataset/actions.rb +15 -6
  70. data/lib/sequel/dataset/graph.rb +15 -5
  71. data/lib/sequel/dataset/misc.rb +12 -4
  72. data/lib/sequel/dataset/mutation.rb +17 -8
  73. data/lib/sequel/dataset/prepared_statements.rb +3 -2
  74. data/lib/sequel/dataset/query.rb +84 -38
  75. data/lib/sequel/dataset/sql.rb +302 -191
  76. data/lib/sequel/deprecated.rb +26 -17
  77. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
  78. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  79. data/lib/sequel/extensions/from_block.rb +1 -0
  80. data/lib/sequel/extensions/graph_each.rb +1 -1
  81. data/lib/sequel/extensions/identifier_mangling.rb +2 -2
  82. data/lib/sequel/extensions/migration.rb +28 -4
  83. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
  84. data/lib/sequel/extensions/schema_dumper.rb +4 -4
  85. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
  86. data/lib/sequel/extensions/set_overrides.rb +2 -0
  87. data/lib/sequel/extensions/split_array_nil.rb +2 -2
  88. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  89. data/lib/sequel/model.rb +11 -7
  90. data/lib/sequel/model/associations.rb +5 -7
  91. data/lib/sequel/model/base.rb +47 -45
  92. data/lib/sequel/model/dataset_module.rb +9 -14
  93. data/lib/sequel/model/plugins.rb +3 -0
  94. data/lib/sequel/no_core_ext.rb +1 -0
  95. data/lib/sequel/plugins/blacklist_security.rb +1 -1
  96. data/lib/sequel/plugins/boolean_subsets.rb +7 -5
  97. data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
  98. data/lib/sequel/plugins/dataset_associations.rb +1 -1
  99. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  100. data/lib/sequel/plugins/finder.rb +240 -0
  101. data/lib/sequel/plugins/inverted_subsets.rb +19 -12
  102. data/lib/sequel/plugins/many_through_many.rb +1 -1
  103. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  104. data/lib/sequel/plugins/schema.rb +1 -1
  105. data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
  106. data/lib/sequel/plugins/subset_conditions.rb +11 -3
  107. data/lib/sequel/plugins/whitelist_security.rb +118 -0
  108. data/lib/sequel/sql.rb +80 -36
  109. data/lib/sequel/timezones.rb +2 -0
  110. data/lib/sequel/version.rb +1 -1
  111. data/spec/adapters/mssql_spec.rb +20 -0
  112. data/spec/adapters/mysql_spec.rb +1 -1
  113. data/spec/adapters/oracle_spec.rb +12 -8
  114. data/spec/adapters/postgres_spec.rb +1 -1
  115. data/spec/adapters/spec_helper.rb +1 -1
  116. data/spec/adapters/sqlite_spec.rb +36 -34
  117. data/spec/core/connection_pool_spec.rb +2 -1
  118. data/spec/core/database_spec.rb +87 -9
  119. data/spec/core/dataset_spec.rb +501 -129
  120. data/spec/core/deprecated_spec.rb +1 -1
  121. data/spec/core/expression_filters_spec.rb +146 -60
  122. data/spec/core/mock_adapter_spec.rb +1 -1
  123. data/spec/core/object_graph_spec.rb +61 -9
  124. data/spec/core/placeholder_literalizer_spec.rb +20 -2
  125. data/spec/core/schema_generator_spec.rb +6 -6
  126. data/spec/core/schema_spec.rb +54 -5
  127. data/spec/core_extensions_spec.rb +122 -18
  128. data/spec/deprecation_helper.rb +27 -2
  129. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
  130. data/spec/extensions/association_proxies_spec.rb +2 -2
  131. data/spec/extensions/auto_literal_strings_spec.rb +212 -0
  132. data/spec/extensions/blacklist_security_spec.rb +1 -0
  133. data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
  134. data/spec/extensions/column_select_spec.rb +20 -8
  135. data/spec/extensions/columns_introspection_spec.rb +3 -3
  136. data/spec/extensions/core_refinements_spec.rb +29 -12
  137. data/spec/extensions/dataset_associations_spec.rb +12 -12
  138. data/spec/extensions/def_dataset_method_spec.rb +100 -0
  139. data/spec/extensions/error_sql_spec.rb +1 -1
  140. data/spec/extensions/finder_spec.rb +260 -0
  141. data/spec/extensions/graph_each_spec.rb +2 -2
  142. data/spec/extensions/identifier_mangling_spec.rb +14 -8
  143. data/spec/extensions/inverted_subsets_spec.rb +4 -4
  144. data/spec/extensions/lazy_attributes_spec.rb +7 -0
  145. data/spec/extensions/many_through_many_spec.rb +38 -14
  146. data/spec/extensions/nested_attributes_spec.rb +18 -6
  147. data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
  148. data/spec/extensions/pg_enum_spec.rb +16 -1
  149. data/spec/extensions/pg_interval_spec.rb +11 -2
  150. data/spec/extensions/pg_loose_count_spec.rb +5 -0
  151. data/spec/extensions/pg_row_spec.rb +25 -0
  152. data/spec/extensions/prepared_statements_spec.rb +10 -1
  153. data/spec/extensions/query_spec.rb +2 -2
  154. data/spec/extensions/schema_dumper_spec.rb +2 -2
  155. data/spec/extensions/schema_spec.rb +2 -2
  156. data/spec/extensions/set_overrides_spec.rb +7 -3
  157. data/spec/extensions/sql_expr_spec.rb +0 -1
  158. data/spec/extensions/subset_conditions_spec.rb +6 -6
  159. data/spec/extensions/table_select_spec.rb +24 -12
  160. data/spec/extensions/to_dot_spec.rb +4 -4
  161. data/spec/extensions/whitelist_security_spec.rb +131 -0
  162. data/spec/integration/dataset_test.rb +9 -5
  163. data/spec/integration/model_test.rb +2 -0
  164. data/spec/integration/plugin_test.rb +2 -2
  165. data/spec/integration/spec_helper.rb +1 -1
  166. data/spec/model/associations_spec.rb +39 -11
  167. data/spec/model/base_spec.rb +44 -24
  168. data/spec/model/class_dataset_methods_spec.rb +18 -16
  169. data/spec/model/dataset_methods_spec.rb +4 -4
  170. data/spec/model/eager_loading_spec.rb +84 -24
  171. data/spec/model/model_spec.rb +97 -63
  172. data/spec/model/record_spec.rb +21 -13
  173. metadata +13 -2
@@ -13,20 +13,29 @@ describe "prepared_statements plugin" do
13
13
  @db.sqls
14
14
  end
15
15
 
16
- it "should correctly lookup by primary key for joined dataset" do
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, :b___mongo
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, :b___mongo
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::Generator dump methods" do
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::Generator
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::Generator)
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::Generator)
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
- @ds = Sequel.mock.dataset.from(:items).extension(:set_overrides).set_defaults(:x=>1)
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
- it "should not affect String update arguments" do
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
- @ds = Sequel.mock.dataset.from(:items).extension(:set_overrides).set_overrides(:x=>1)
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.subset(:active, :active)
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 not add a table.* selection on existing dataset with multiple tables" do
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{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\\\"\"];"]
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{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\"];"]
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{}.over(:partition=>:group_id, :order=>:id).as(:rank)}.all.
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{}.over(:order=>id).as(:rank)}.all.
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
- csc[:collate] = @db.dataset_class::CASE_SENSITIVE_COLLATION if defined? @db.dataset_class::CASE_SENSITIVE_COLLATION
1572
- cic[:collate] = @db.dataset_class::CASE_INSENSITIVE_COLLATION if defined? @db.dataset_class::CASE_INSENSITIVE_COLLATION
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
- @ds = @db[:a].order(:a).extension(:set_overrides)
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