sequel 3.21.0 → 3.32.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.
- data/CHANGELOG +539 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/advanced_associations.rdoc +17 -0
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +89 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +129 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +5 -7
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +52 -0
- data/lib/sequel/adapters/jdbc/derby.rb +260 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +66 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +177 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
- data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +231 -78
- data/lib/sequel/adapters/mock.rb +339 -0
- data/lib/sequel/adapters/mysql.rb +85 -184
- data/lib/sequel/adapters/mysql2.rb +26 -25
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +1 -6
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +355 -53
- data/lib/sequel/adapters/postgres.rb +194 -33
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +328 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +278 -107
- data/lib/sequel/adapters/shared/mysql.rb +203 -65
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +237 -46
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +200 -50
- data/lib/sequel/adapters/sqlite.rb +29 -21
- data/lib/sequel/adapters/swift/mysql.rb +12 -7
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +160 -19
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +68 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +104 -19
- data/lib/sequel/database/query.rb +163 -59
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +240 -76
- data/lib/sequel/dataset/features.rb +91 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +59 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +676 -267
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/query.rb +1 -1
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1081 -344
- data/lib/sequel/model/base.rb +420 -133
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +20 -10
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +43 -10
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +68 -7
- data/lib/sequel/plugins/nested_attributes.rb +65 -10
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +109 -52
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +135 -30
- data/spec/adapters/mysql_spec.rb +244 -212
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +267 -78
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +21 -30
- data/spec/core/database_spec.rb +789 -512
- data/spec/core/dataset_spec.rb +1176 -1061
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +419 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +114 -22
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +53 -0
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/migration_spec.rb +35 -32
- data/spec/extensions/named_timezones_spec.rb +23 -3
- data/spec/extensions/nested_attributes_spec.rb +97 -88
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +53 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/query_spec.rb +6 -0
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +5 -8
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +81 -43
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +18 -29
- data/spec/extensions/spec_helper.rb +13 -61
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +661 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +500 -67
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +367 -119
- data/spec/integration/prepared_statement_test.rb +222 -125
- data/spec/integration/schema_test.rb +217 -39
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +182 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +955 -662
- data/spec/model/base_spec.rb +275 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +222 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +381 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +117 -73
|
@@ -2,218 +2,245 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
|
2
2
|
|
|
3
3
|
describe "Prepared Statements and Bound Arguments" do
|
|
4
4
|
before do
|
|
5
|
-
INTEGRATION_DB
|
|
5
|
+
@db = INTEGRATION_DB
|
|
6
|
+
@db.create_table!(:items) do
|
|
6
7
|
primary_key :id
|
|
7
|
-
integer :
|
|
8
|
+
integer :numb
|
|
8
9
|
end
|
|
9
10
|
@c = Class.new(Sequel::Model(:items))
|
|
10
|
-
@ds =
|
|
11
|
-
@ds.insert(:
|
|
12
|
-
@ds.
|
|
13
|
-
prepared_arg_placeholder == '$' ? :"#{sym}__int" : sym
|
|
14
|
-
end
|
|
11
|
+
@ds = @db[:items]
|
|
12
|
+
@ds.insert(:numb=>10)
|
|
13
|
+
@pr = @ds.requires_placeholder_type_specifiers? ? proc{|i| :"#{i}__integer"} : proc{|i| i}
|
|
15
14
|
end
|
|
16
15
|
after do
|
|
17
|
-
|
|
16
|
+
@db.drop_table(:items)
|
|
18
17
|
end
|
|
19
18
|
|
|
20
|
-
specify "should support bound variables
|
|
21
|
-
@ds.filter(:
|
|
22
|
-
@ds.filter(:
|
|
23
|
-
@ds.filter(:
|
|
19
|
+
specify "should support bound variables when selecting" do
|
|
20
|
+
@ds.filter(:numb=>:$n).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
21
|
+
@ds.filter(:numb=>:$n).call(:all, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
22
|
+
@ds.filter(:numb=>:$n).call(:first, :n=>10).should == {:id=>1, :numb=>10}
|
|
23
|
+
@ds.filter(:numb=>:$n).call([:map, :numb], :n=>10).should == [10]
|
|
24
|
+
@ds.filter(:numb=>:$n).call([:to_hash, :id, :numb], :n=>10).should == {1=>10}
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
specify "should support blocks for select and
|
|
27
|
-
@ds.filter(:
|
|
28
|
-
@ds.filter(:
|
|
27
|
+
specify "should support blocks for select, all, and map " do
|
|
28
|
+
@ds.filter(:numb=>:$n).call(:select, :n=>10){|r| r[:numb] *= 2}.should == [{:id=>1, :numb=>20}]
|
|
29
|
+
@ds.filter(:numb=>:$n).call(:all, :n=>10){|r| r[:numb] *= 2}.should == [{:id=>1, :numb=>20}]
|
|
30
|
+
@ds.filter(:numb=>:$n).call([:map], :n=>10){|r| r[:numb] * 2}.should == [20]
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
specify "should support binding variables before the call with #bind" do
|
|
32
|
-
@ds.filter(:
|
|
33
|
-
@ds.filter(:
|
|
34
|
-
@ds.filter(:
|
|
34
|
+
@ds.filter(:numb=>:$n).bind(:n=>10).call(:select).should == [{:id=>1, :numb=>10}]
|
|
35
|
+
@ds.filter(:numb=>:$n).bind(:n=>10).call(:all).should == [{:id=>1, :numb=>10}]
|
|
36
|
+
@ds.filter(:numb=>:$n).bind(:n=>10).call(:first).should == {:id=>1, :numb=>10}
|
|
35
37
|
|
|
36
|
-
@ds.bind(:n=>10).filter(:
|
|
37
|
-
@ds.bind(:n=>10).filter(:
|
|
38
|
-
@ds.bind(:n=>10).filter(:
|
|
38
|
+
@ds.bind(:n=>10).filter(:numb=>:$n).call(:select).should == [{:id=>1, :numb=>10}]
|
|
39
|
+
@ds.bind(:n=>10).filter(:numb=>:$n).call(:all).should == [{:id=>1, :numb=>10}]
|
|
40
|
+
@ds.bind(:n=>10).filter(:numb=>:$n).call(:first).should == {:id=>1, :numb=>10}
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
specify "should allow overriding variables specified with #bind" do
|
|
42
|
-
@ds.filter(:
|
|
43
|
-
@ds.filter(:
|
|
44
|
-
@ds.filter(:
|
|
44
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
45
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).call(:all, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
46
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).call(:first, :n=>10).should == {:id=>1, :numb=>10}
|
|
45
47
|
|
|
46
|
-
@ds.filter(:
|
|
47
|
-
@ds.filter(:
|
|
48
|
-
@ds.filter(:
|
|
48
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:select).should == [{:id=>1, :numb=>10}]
|
|
49
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:all).should == [{:id=>1, :numb=>10}]
|
|
50
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:first).should == {:id=>1, :numb=>10}
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
specify "should support placeholder literal strings with call" do
|
|
52
|
-
@ds.filter("
|
|
54
|
+
@ds.filter("numb = ?", :$n).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
specify "should support named placeholder literal strings and handle multiple named placeholders correctly with call" do
|
|
56
|
-
@ds.filter("
|
|
57
|
-
@ds.insert(:
|
|
58
|
-
@ds.insert(:
|
|
59
|
-
@ds.filter("
|
|
58
|
+
@ds.filter("numb = :n", :n=>:$n).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
59
|
+
@ds.insert(:numb=>20)
|
|
60
|
+
@ds.insert(:numb=>30)
|
|
61
|
+
@ds.filter("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :numb=>20}]
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
specify "should support datasets with static sql and placeholders with call" do
|
|
63
|
-
|
|
65
|
+
@db["SELECT * FROM items WHERE numb = ?", :$n].call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
specify "should support subselects with call" do
|
|
67
|
-
@ds.filter(:id=>:$i).filter(:
|
|
69
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
specify "should support subselects with exists with call" do
|
|
73
|
+
@ds.filter(:id=>:$i).filter(@ds.select(:numb).filter(:numb=>:$n).exists).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
|
|
68
74
|
end
|
|
69
75
|
|
|
70
76
|
specify "should support subselects with literal strings with call" do
|
|
71
|
-
@ds.filter(:id=>:$i, :
|
|
77
|
+
@ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter("numb = ?", :$n)).call(:select, :n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
|
|
72
78
|
end
|
|
73
79
|
|
|
74
80
|
specify "should support subselects with static sql and placeholders with call" do
|
|
75
|
-
@ds.filter(:id=>:$i, :
|
|
81
|
+
@ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).call(:select, :n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
|
|
76
82
|
end
|
|
77
83
|
|
|
78
84
|
specify "should support subselects of subselects with call" do
|
|
79
|
-
@ds.filter(:id=>:$i).filter(:
|
|
85
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
|
|
80
86
|
end
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
@ds.insert(:
|
|
84
|
-
ds = @ds.limit(
|
|
85
|
-
ds.call(:select, :n=>1, :n2=>0).should == [{:id=>1, :
|
|
86
|
-
ds.call(:select, :n=>1, :n2=>1).should == [{:id=>2, :
|
|
88
|
+
cspecify "should support using a bound variable for a limit and offset", [:jdbc, :db2] do
|
|
89
|
+
@ds.insert(:numb=>20)
|
|
90
|
+
ds = @ds.limit(:$n, :$n2).order(:id)
|
|
91
|
+
ds.call(:select, :n=>1, :n2=>0).should == [{:id=>1, :numb=>10}]
|
|
92
|
+
ds.call(:select, :n=>1, :n2=>1).should == [{:id=>2, :numb=>20}]
|
|
87
93
|
ds.call(:select, :n=>1, :n2=>2).should == []
|
|
88
|
-
ds.call(:select, :n=>2, :n2=>0).should == [{:id=>1, :
|
|
89
|
-
ds.call(:select, :n=>2, :n2=>1).should == [{:id=>2, :
|
|
94
|
+
ds.call(:select, :n=>2, :n2=>0).should == [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
|
|
95
|
+
ds.call(:select, :n=>2, :n2=>1).should == [{:id=>2, :numb=>20}]
|
|
90
96
|
end
|
|
91
97
|
|
|
92
98
|
specify "should support bound variables with insert" do
|
|
93
|
-
@ds.call(:insert, {:n=>20}, :
|
|
99
|
+
@ds.call(:insert, {:n=>20}, :numb=>:$n)
|
|
94
100
|
@ds.count.should == 2
|
|
95
|
-
@ds.order(:id).map(:
|
|
101
|
+
@ds.order(:id).map(:numb).should == [10, 20]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
specify "should support bound variables with NULL values" do
|
|
105
|
+
@ds.delete
|
|
106
|
+
@ds.call(:insert, {:n=>nil}, :numb=>@pr[:$n])
|
|
107
|
+
@ds.count.should == 1
|
|
108
|
+
@ds.map(:numb).should == [nil]
|
|
96
109
|
end
|
|
97
110
|
|
|
98
111
|
specify "should have insert return primary key value when using bound arguments" do
|
|
99
|
-
@ds.call(:insert, {:n=>20}, :
|
|
100
|
-
@ds.filter(:id=>2).first[:
|
|
112
|
+
@ds.call(:insert, {:n=>20}, :numb=>:$n).should == 2
|
|
113
|
+
@ds.filter(:id=>2).first[:numb].should == 20
|
|
101
114
|
end
|
|
102
115
|
|
|
103
116
|
specify "should support bound variables with delete" do
|
|
104
|
-
@ds.filter(:
|
|
117
|
+
@ds.filter(:numb=>:$n).call(:delete, :n=>10).should == 1
|
|
105
118
|
@ds.count.should == 0
|
|
106
119
|
end
|
|
107
120
|
|
|
108
121
|
specify "should support bound variables with update" do
|
|
109
|
-
@ds.filter(:
|
|
110
|
-
@ds.all.should == [{:id=>1, :
|
|
122
|
+
@ds.filter(:numb=>:$n).call(:update, {:n=>10, :nn=>20}, :numb=>:numb+:$nn).should == 1
|
|
123
|
+
@ds.all.should == [{:id=>1, :numb=>30}]
|
|
111
124
|
end
|
|
112
125
|
|
|
113
|
-
specify "should support prepared statements
|
|
114
|
-
@ds.filter(:
|
|
115
|
-
|
|
116
|
-
@ds.filter(:
|
|
117
|
-
|
|
118
|
-
@ds.filter(:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
specify "should support prepared statements when selecting" do
|
|
127
|
+
@ds.filter(:numb=>:$n).prepare(:select, :select_n)
|
|
128
|
+
@db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
129
|
+
@ds.filter(:numb=>:$n).prepare(:all, :select_n)
|
|
130
|
+
@db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
131
|
+
@ds.filter(:numb=>:$n).prepare(:first, :select_n)
|
|
132
|
+
@db.call(:select_n, :n=>10).should == {:id=>1, :numb=>10}
|
|
133
|
+
@ds.filter(:numb=>:$n).prepare([:map, :numb], :select_n)
|
|
134
|
+
@db.call(:select_n, :n=>10).should == [10]
|
|
135
|
+
@ds.filter(:numb=>:$n).prepare([:to_hash, :id, :numb], :select_n)
|
|
136
|
+
@db.call(:select_n, :n=>10).should == {1=>10}
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
specify "should support prepared statements being call multiple times with different arguments" do
|
|
140
|
+
@ds.filter(:numb=>:$n).prepare(:select, :select_n)
|
|
141
|
+
@db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
142
|
+
@db.call(:select_n, :n=>0).should == []
|
|
143
|
+
@db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
|
|
125
144
|
end
|
|
126
145
|
|
|
127
146
|
specify "should support placeholder literal strings with prepare" do
|
|
128
|
-
@ds.filter("
|
|
147
|
+
@ds.filter("numb = ?", :$n).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :numb=>10}]
|
|
129
148
|
end
|
|
130
149
|
|
|
131
150
|
specify "should support named placeholder literal strings and handle multiple named placeholders correctly with prepare" do
|
|
132
|
-
@ds.filter("
|
|
133
|
-
@ds.insert(:
|
|
134
|
-
@ds.insert(:
|
|
135
|
-
@ds.filter("
|
|
151
|
+
@ds.filter("numb = :n", :n=>:$n).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :numb=>10}]
|
|
152
|
+
@ds.insert(:numb=>20)
|
|
153
|
+
@ds.insert(:numb=>30)
|
|
154
|
+
@ds.filter("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :numb=>20}]
|
|
136
155
|
end
|
|
137
156
|
|
|
138
157
|
specify "should support datasets with static sql and placeholders with prepare" do
|
|
139
|
-
|
|
158
|
+
@db["SELECT * FROM items WHERE numb = ?", :$n].prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :numb=>10}]
|
|
140
159
|
end
|
|
141
160
|
|
|
142
161
|
specify "should support subselects with prepare" do
|
|
143
|
-
@ds.filter(:id=>:$i).filter(:
|
|
162
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
specify "should support subselects with exists with prepare" do
|
|
166
|
+
@ds.filter(:id=>:$i).filter(@ds.select(:numb).filter(:numb=>:$n).exists).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
|
|
144
167
|
end
|
|
145
168
|
|
|
146
169
|
specify "should support subselects with literal strings with prepare" do
|
|
147
|
-
@ds.filter(:id=>:$i, :
|
|
170
|
+
@ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter("numb = ?", :$n)).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
|
|
148
171
|
end
|
|
149
172
|
|
|
150
173
|
specify "should support subselects with static sql and placeholders with prepare" do
|
|
151
|
-
@ds.filter(:id=>:$i, :
|
|
174
|
+
@ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
|
|
152
175
|
end
|
|
153
176
|
|
|
154
177
|
specify "should support subselects of subselects with prepare" do
|
|
155
|
-
@ds.filter(:id=>:$i).filter(:
|
|
178
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
|
|
156
179
|
end
|
|
157
180
|
|
|
158
|
-
|
|
159
|
-
@ds.insert(:
|
|
160
|
-
ps = @ds.limit(
|
|
161
|
-
ps.call(:n=>1, :n2=>0).should == [{:id=>1, :
|
|
162
|
-
ps.call(:n=>1, :n2=>1).should == [{:id=>2, :
|
|
181
|
+
cspecify "should support using a prepared_statement for a limit and offset", :db2 do
|
|
182
|
+
@ds.insert(:numb=>20)
|
|
183
|
+
ps = @ds.limit(:$n, :$n2).order(:id).prepare(:select, :seq_select)
|
|
184
|
+
ps.call(:n=>1, :n2=>0).should == [{:id=>1, :numb=>10}]
|
|
185
|
+
ps.call(:n=>1, :n2=>1).should == [{:id=>2, :numb=>20}]
|
|
163
186
|
ps.call(:n=>1, :n2=>2).should == []
|
|
164
|
-
ps.call(:n=>2, :n2=>0).should == [{:id=>1, :
|
|
165
|
-
ps.call(:n=>2, :n2=>1).should == [{:id=>2, :
|
|
187
|
+
ps.call(:n=>2, :n2=>0).should == [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
|
|
188
|
+
ps.call(:n=>2, :n2=>1).should == [{:id=>2, :numb=>20}]
|
|
166
189
|
end
|
|
167
190
|
|
|
168
191
|
specify "should support prepared statements with insert" do
|
|
169
|
-
@ds.prepare(:insert, :insert_n, :
|
|
170
|
-
|
|
192
|
+
@ds.prepare(:insert, :insert_n, :numb=>:$n)
|
|
193
|
+
@db.call(:insert_n, :n=>20)
|
|
171
194
|
@ds.count.should == 2
|
|
172
|
-
@ds.order(:id).map(:
|
|
195
|
+
@ds.order(:id).map(:numb).should == [10, 20]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
specify "should support prepared statements with NULL values" do
|
|
199
|
+
@ds.delete
|
|
200
|
+
@ds.prepare(:insert, :insert_n, :numb=>@pr[:$n])
|
|
201
|
+
@db.call(:insert_n, :n=>nil)
|
|
202
|
+
@ds.count.should == 1
|
|
203
|
+
@ds.map(:numb).should == [nil]
|
|
173
204
|
end
|
|
174
205
|
|
|
175
206
|
specify "should have insert return primary key value when using prepared statements" do
|
|
176
|
-
@ds.prepare(:insert, :insert_n, :
|
|
177
|
-
|
|
178
|
-
@ds.filter(:id=>2).first[:
|
|
207
|
+
@ds.prepare(:insert, :insert_n, :numb=>:$n)
|
|
208
|
+
@db.call(:insert_n, :n=>20).should == 2
|
|
209
|
+
@ds.filter(:id=>2).first[:numb].should == 20
|
|
179
210
|
end
|
|
180
211
|
|
|
181
212
|
specify "should support prepared statements with delete" do
|
|
182
|
-
@ds.filter(:
|
|
183
|
-
|
|
213
|
+
@ds.filter(:numb=>:$n).prepare(:delete, :delete_n)
|
|
214
|
+
@db.call(:delete_n, :n=>10).should == 1
|
|
184
215
|
@ds.count.should == 0
|
|
185
216
|
end
|
|
186
217
|
|
|
187
218
|
specify "should support prepared statements with update" do
|
|
188
|
-
@ds.filter(:
|
|
189
|
-
|
|
190
|
-
@ds.all.should == [{:id=>1, :
|
|
219
|
+
@ds.filter(:numb=>:$n).prepare(:update, :update_n, :numb=>:numb+:$nn)
|
|
220
|
+
@db.call(:update_n, :n=>10, :nn=>20).should == 1
|
|
221
|
+
@ds.all.should == [{:id=>1, :numb=>30}]
|
|
191
222
|
end
|
|
192
223
|
|
|
193
224
|
specify "model datasets should return model instances when using select, all, and first with bound variables" do
|
|
194
|
-
@c.filter(:
|
|
195
|
-
@c.filter(:
|
|
196
|
-
@c.filter(:
|
|
225
|
+
@c.filter(:numb=>:$n).call(:select, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
|
|
226
|
+
@c.filter(:numb=>:$n).call(:all, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
|
|
227
|
+
@c.filter(:numb=>:$n).call(:first, :n=>10).should == @c.load(:id=>1, :numb=>10)
|
|
197
228
|
end
|
|
198
229
|
|
|
199
230
|
specify "model datasets should return model instances when using select, all, and first with prepared statements" do
|
|
200
|
-
@c.filter(:
|
|
201
|
-
|
|
202
|
-
@c.filter(:
|
|
203
|
-
|
|
204
|
-
@c.filter(:
|
|
205
|
-
|
|
206
|
-
if INTEGRATION_DB.adapter_scheme == :jdbc and INTEGRATION_DB.database_type == :sqlite
|
|
207
|
-
# Work around for open prepared statements on a table not allowing the
|
|
208
|
-
# dropping of a table when using SQLite over JDBC
|
|
209
|
-
INTEGRATION_DB.synchronize{|c| c.prepared_statements[:select_n][1].close}
|
|
210
|
-
end
|
|
231
|
+
@c.filter(:numb=>:$n).prepare(:select, :select_n1)
|
|
232
|
+
@db.call(:select_n1, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
|
|
233
|
+
@c.filter(:numb=>:$n).prepare(:all, :select_n1)
|
|
234
|
+
@db.call(:select_n1, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
|
|
235
|
+
@c.filter(:numb=>:$n).prepare(:first, :select_n1)
|
|
236
|
+
@db.call(:select_n1, :n=>10).should == @c.load(:id=>1, :numb=>10)
|
|
211
237
|
end
|
|
212
238
|
end
|
|
213
239
|
|
|
214
240
|
describe "Bound Argument Types" do
|
|
215
|
-
before do
|
|
216
|
-
INTEGRATION_DB
|
|
241
|
+
before(:all) do
|
|
242
|
+
@db = INTEGRATION_DB
|
|
243
|
+
@db.create_table!(:items) do
|
|
217
244
|
primary_key :id
|
|
218
245
|
Date :d
|
|
219
246
|
DateTime :dt
|
|
@@ -223,7 +250,7 @@ describe "Bound Argument Types" do
|
|
|
223
250
|
Float :f
|
|
224
251
|
TrueClass :b
|
|
225
252
|
end
|
|
226
|
-
@ds =
|
|
253
|
+
@ds = @db[:items]
|
|
227
254
|
@vs = {:d=>Date.civil(2010, 10, 11), :dt=>DateTime.civil(2010, 10, 12, 13, 14, 15), :f=>1.0, :s=>'str', :t=>Time.at(20101010), :file=>Sequel::SQL::Blob.new('blob'), :b=>true}
|
|
228
255
|
@ds.insert(@vs)
|
|
229
256
|
@ds.meta_def(:ba) do |sym, type|
|
|
@@ -232,39 +259,109 @@ describe "Bound Argument Types" do
|
|
|
232
259
|
end
|
|
233
260
|
after do
|
|
234
261
|
Sequel.datetime_class = Time
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
INTEGRATION_DB.drop_table(:items)
|
|
262
|
+
end
|
|
263
|
+
after(:all) do
|
|
264
|
+
@db.drop_table(:items)
|
|
239
265
|
end
|
|
240
266
|
|
|
241
|
-
cspecify "should handle date type", [:do, :sqlite], :mssql, [:jdbc, :sqlite] do
|
|
242
|
-
@ds.filter(:d
|
|
267
|
+
cspecify "should handle date type", [:do, :sqlite], :mssql, [:jdbc, :sqlite], :oracle do
|
|
268
|
+
@ds.filter(:d=>:$x).prepare(:first, :ps_date).call(:x=>@vs[:d])[:d].should == @vs[:d]
|
|
243
269
|
end
|
|
244
270
|
|
|
245
|
-
cspecify "should handle datetime type", [:do], [:mysql2], [:swift], [:jdbc, :sqlite], [:tinytds] do
|
|
271
|
+
cspecify "should handle datetime type", [:do], [:mysql2], [:swift], [:jdbc, :sqlite], [:tinytds], [:oracle] do
|
|
246
272
|
Sequel.datetime_class = DateTime
|
|
247
|
-
@ds.filter(:dt
|
|
273
|
+
@ds.filter(:dt=>:$x).prepare(:first, :ps_datetime).call(:x=>@vs[:dt])[:dt].should == @vs[:dt]
|
|
248
274
|
end
|
|
249
275
|
|
|
250
|
-
cspecify "should handle time type", [:do], [:jdbc, :sqlite] do
|
|
251
|
-
@ds.filter(:t
|
|
276
|
+
cspecify "should handle time type", [:do], [:jdbc, :sqlite], [:oracle] do
|
|
277
|
+
@ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].should == @vs[:t]
|
|
252
278
|
end
|
|
253
279
|
|
|
254
|
-
cspecify "should handle blob type", [:swift] do
|
|
255
|
-
@ds.filter(:file
|
|
280
|
+
cspecify "should handle blob type", [:swift], [:odbc], [:jdbc, :db2], :oracle, :derby do
|
|
281
|
+
@ds.filter(:file=>:$x).prepare(:first, :ps_blob).call(:x=>@vs[:file])[:file].should == @vs[:file]
|
|
256
282
|
end
|
|
257
283
|
|
|
258
284
|
cspecify "should handle float type", [:swift, :sqlite] do
|
|
259
|
-
@ds.filter(:f
|
|
285
|
+
@ds.filter(:f=>:$x).prepare(:first, :ps_float).call(:x=>@vs[:f])[:f].should == @vs[:f]
|
|
260
286
|
end
|
|
261
287
|
|
|
262
288
|
specify "should handle string type" do
|
|
263
|
-
@ds.filter(:s
|
|
289
|
+
@ds.filter(:s=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:s])[:s].should == @vs[:s]
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
cspecify "should handle boolean type", [:do, :sqlite], [:odbc, :mssql], [:jdbc, :sqlite], [:jdbc, :db2], :oracle do
|
|
293
|
+
@ds.filter(:b=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:b])[:b].should == @vs[:b]
|
|
264
294
|
end
|
|
295
|
+
end unless Sequel.guarded?([:swift, :postgres])
|
|
265
296
|
|
|
266
|
-
|
|
267
|
-
|
|
297
|
+
describe "Dataset#unbind" do
|
|
298
|
+
before do
|
|
299
|
+
@ds = ds = INTEGRATION_DB[:items]
|
|
300
|
+
@ct = proc do |t, v|
|
|
301
|
+
INTEGRATION_DB.create_table!(:items) do
|
|
302
|
+
column :c, t
|
|
303
|
+
end
|
|
304
|
+
ds.insert(:c=>v)
|
|
305
|
+
end
|
|
306
|
+
@u = proc{|ds| ds, bv = ds.unbind; ds.call(:first, bv)}
|
|
307
|
+
end
|
|
308
|
+
after do
|
|
309
|
+
INTEGRATION_DB.drop_table(:items) rescue nil
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
specify "should unbind values assigned to equality and inequality statements" do
|
|
313
|
+
@ct[Integer, 10]
|
|
314
|
+
@u[@ds.filter(:c=>10)].should == {:c=>10}
|
|
315
|
+
@u[@ds.exclude(:c=>10)].should == nil
|
|
316
|
+
@u[@ds.filter{c < 10}].should == nil
|
|
317
|
+
@u[@ds.filter{c <= 10}].should == {:c=>10}
|
|
318
|
+
@u[@ds.filter{c > 10}].should == nil
|
|
319
|
+
@u[@ds.filter{c >= 10}].should == {:c=>10}
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
cspecify "should handle numerics and strings", [:odbc], [:swift, :sqlite] do
|
|
323
|
+
@ct[Integer, 10]
|
|
324
|
+
@u[@ds.filter(:c=>10)].should == {:c=>10}
|
|
325
|
+
@ct[Float, 0.0]
|
|
326
|
+
@u[@ds.filter{c < 1}].should == {:c=>0.0}
|
|
327
|
+
@ct[String, 'foo']
|
|
328
|
+
@u[@ds.filter(:c=>'foo')].should == {:c=>'foo'}
|
|
329
|
+
|
|
330
|
+
INTEGRATION_DB.create_table!(:items) do
|
|
331
|
+
BigDecimal :c, :size=>[15,2]
|
|
332
|
+
end
|
|
333
|
+
@ds.insert(:c=>BigDecimal.new('1.1'))
|
|
334
|
+
@u[@ds.filter{c > 0}].should == {:c=>BigDecimal.new('1.1')}
|
|
268
335
|
end
|
|
269
|
-
end unless INTEGRATION_DB.adapter_scheme == :swift && INTEGRATION_DB.database_type == :postgres
|
|
270
336
|
|
|
337
|
+
cspecify "should handle dates and times", [:do], [:jdbc, :mssql], [:jdbc, :sqlite], [:tinytds], :oracle do
|
|
338
|
+
@ct[Date, Date.today]
|
|
339
|
+
@u[@ds.filter(:c=>Date.today)].should == {:c=>Date.today}
|
|
340
|
+
t = Time.now
|
|
341
|
+
@ct[Time, t]
|
|
342
|
+
@u[@ds.filter{c < t + 1}][:c].to_i.should == t.to_i
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
specify "should handle QualifiedIdentifiers" do
|
|
346
|
+
@ct[Integer, 10]
|
|
347
|
+
@u[@ds.filter{items__c > 1}].should == {:c=>10}
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
specify "should handle deep nesting" do
|
|
351
|
+
INTEGRATION_DB.create_table!(:items) do
|
|
352
|
+
Integer :a
|
|
353
|
+
Integer :b
|
|
354
|
+
Integer :c
|
|
355
|
+
Integer :d
|
|
356
|
+
end
|
|
357
|
+
@ds.insert(:a=>2, :b=>0, :c=>3, :d=>5)
|
|
358
|
+
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and({~{:d=>4}=>1}.case(0) => 1)].should == {:a=>2, :b=>0, :c=>3, :d=>5}
|
|
359
|
+
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and({~{:d=>5}=>1}.case(0) => 1)].should == nil
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
specify "should handle case where the same variable has the same value in multiple places " do
|
|
363
|
+
@ct[Integer, 1]
|
|
364
|
+
@u[@ds.filter{c > 1}.or{c < 1}.invert].should == {:c=>1}
|
|
365
|
+
@u[@ds.filter{c > 1}.or{c < 1}].should == nil
|
|
366
|
+
end
|
|
367
|
+
end
|