sequel 3.21.0 → 3.31.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 +485 -3
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +249 -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/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 +45 -0
- data/lib/sequel/adapters/jdbc/derby.rb +247 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +56 -29
- data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -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 +81 -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 +335 -0
- data/lib/sequel/adapters/mysql.rb +82 -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 +351 -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 +321 -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 +231 -106
- data/lib/sequel/adapters/shared/mysql.rb +181 -63
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +231 -41
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +4 -7
- data/lib/sequel/adapters/shared/sqlite.rb +201 -57
- 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 +46 -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 +153 -58
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +231 -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 +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +48 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +665 -253
- 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/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1020 -337
- data/lib/sequel/model/base.rb +414 -132
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- 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 +65 -7
- 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 +88 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -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 +111 -29
- data/spec/adapters/mysql_spec.rb +135 -123
- data/spec/adapters/oracle_spec.rb +49 -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 +788 -512
- data/spec/core/dataset_spec.rb +1073 -1053
- 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/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/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 +37 -0
- data/spec/extensions/serialization_spec.rb +72 -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 +537 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +461 -65
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +212 -122
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +865 -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 +309 -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 +115 -73
|
@@ -2,16 +2,16 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
|
2
2
|
|
|
3
3
|
describe "Simple Dataset operations" do
|
|
4
4
|
before do
|
|
5
|
-
INTEGRATION_DB
|
|
5
|
+
@db = INTEGRATION_DB
|
|
6
|
+
@db.create_table!(:items) do
|
|
6
7
|
primary_key :id
|
|
7
8
|
Integer :number
|
|
8
9
|
end
|
|
9
|
-
@ds =
|
|
10
|
+
@ds = @db[:items]
|
|
10
11
|
@ds.insert(:number=>10)
|
|
11
|
-
clear_sqls
|
|
12
12
|
end
|
|
13
13
|
after do
|
|
14
|
-
|
|
14
|
+
@db.drop_table(:items)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
specify "should support sequential primary keys" do
|
|
@@ -23,7 +23,7 @@ describe "Simple Dataset operations" do
|
|
|
23
23
|
{:id => 3, :number=>30} ]
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
cspecify "should insert with a primary key specified", :mssql do
|
|
26
|
+
cspecify "should insert with a primary key specified", :db2, :mssql do
|
|
27
27
|
@ds.insert(:id=>100, :number=>20)
|
|
28
28
|
@ds.count.should == 2
|
|
29
29
|
@ds.order(:id).all.should == [{:id=>1, :number=>10}, {:id=>100, :number=>20}]
|
|
@@ -34,6 +34,43 @@ describe "Simple Dataset operations" do
|
|
|
34
34
|
@ds.filter(:id=>2).first[:number].should == 20
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
specify "should have insert work correctly with static SQL" do
|
|
38
|
+
@db["INSERT INTO #{@ds.literal(:items)} (#{@ds.literal(:number)}) VALUES (20)"].insert
|
|
39
|
+
@ds.filter(:id=>2).first[:number].should == 20
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
specify "should have insert_multiple return primary key values" do
|
|
43
|
+
@ds.insert_multiple([{:number=>20}, {:number=>30}]).should == [2, 3]
|
|
44
|
+
@ds.filter(:id=>2).get(:number).should == 20
|
|
45
|
+
@ds.filter(:id=>3).get(:number).should == 30
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
specify "should join correctly" do
|
|
49
|
+
@ds.join(:items___b, :id=>:id).select_all(:items).all.should == [{:id=>1, :number=>10}]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
specify "should correctly deal with qualified columns and subselects" do
|
|
53
|
+
@ds.from_self(:alias=>:a).select(:a__id, :number.qualify(:a)).all.should == [{:id=>1, :number=>10}]
|
|
54
|
+
@ds.join(@ds.as(:a), :id=>:id).select(:a__id, :number.qualify(:a)).all.should == [{:id=>1, :number=>10}]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
specify "should graph correctly" do
|
|
58
|
+
@ds.graph(:items, {:id=>:id}, :table_alias=>:b).all.should == [{:items=>{:id=>1, :number=>10}, :b=>{:id=>1, :number=>10}}]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
specify "should graph correctly with a subselect" do
|
|
62
|
+
@ds.from_self(:alias=>:items).graph(@ds.from_self, {:id=>:id}, :table_alias=>:b).all.should == [{:items=>{:id=>1, :number=>10}, :b=>{:id=>1, :number=>10}}]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
cspecify "should have insert work correctly when inserting a row with all NULL values", :hsqldb do
|
|
66
|
+
@db.create_table!(:items) do
|
|
67
|
+
String :name
|
|
68
|
+
Integer :number
|
|
69
|
+
end
|
|
70
|
+
proc{@ds.insert}.should_not raise_error
|
|
71
|
+
@ds.all.should == [{:name=>nil, :number=>nil}]
|
|
72
|
+
end
|
|
73
|
+
|
|
37
74
|
specify "should delete correctly" do
|
|
38
75
|
@ds.filter(1=>1).delete.should == 1
|
|
39
76
|
@ds.count.should == 0
|
|
@@ -79,13 +116,60 @@ describe "Simple Dataset operations" do
|
|
|
79
116
|
@ds.order(:id).limit(2, 1).all.should == [{:id=>2, :number=>20}]
|
|
80
117
|
end
|
|
81
118
|
|
|
82
|
-
|
|
119
|
+
specify "should provide correct columns when using a limit and offset" do
|
|
120
|
+
ds = @ds.order(:id).limit(1, 1)
|
|
121
|
+
ds.all
|
|
122
|
+
ds.columns.should == [:id, :number]
|
|
123
|
+
@ds.order(:id).limit(1, 1).columns.should == [:id, :number]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
specify "should fetch correctly with a limit and offset for different combinations of from and join tables" do
|
|
127
|
+
@db.create_table!(:items2){primary_key :id2; Integer :number2}
|
|
128
|
+
@db[:items2].insert(:number2=>10)
|
|
129
|
+
@ds.from(:items, :items2).order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10, :id2=>1, :number2=>10}]
|
|
130
|
+
@ds.from(:items___i, :items2___i2).order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10, :id2=>1, :number2=>10}]
|
|
131
|
+
@ds.cross_join(:items2).order(:id).limit(2, 0).all.should ==[{:id=>1, :number=>10, :id2=>1, :number2=>10}]
|
|
132
|
+
@ds.from(:items___i).cross_join(:items2___i2).order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10, :id2=>1, :number2=>10}]
|
|
133
|
+
@ds.cross_join(:items2___i).cross_join(@db[:items2].select(:id2___id3, :number2___number3)).order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10, :id2=>1, :number2=>10, :id3=>1, :number3=>10}]
|
|
134
|
+
|
|
135
|
+
@ds.from(:items, :items2).order(:id).limit(2, 1).all.should == []
|
|
136
|
+
@ds.from(:items___i, :items2___i2).order(:id).limit(2, 1).all.should == []
|
|
137
|
+
@ds.cross_join(:items2).order(:id).limit(2, 1).all.should == []
|
|
138
|
+
@ds.from(:items___i).cross_join(:items2___i2).order(:id).limit(2, 1).all.should == []
|
|
139
|
+
@ds.cross_join(:items2___i).cross_join(@db[:items2].select(:id2___id3, :number2___number3)).order(:id).limit(2, 1).all.should == []
|
|
140
|
+
@db.drop_table(:items2)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
cspecify "should fetch correctly with a limit and offset without an order", :db2, :mssql, :oracle do
|
|
83
144
|
@ds.limit(2, 1).all.should == []
|
|
84
145
|
end
|
|
85
146
|
|
|
147
|
+
specify "should fetch correctly with a limit in an IN subselect" do
|
|
148
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(2)).all.should == [{:id=>1, :number=>10}]
|
|
149
|
+
@ds.insert(:number=>20)
|
|
150
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(1)).all.should == [{:id=>1, :number=>10}]
|
|
151
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(2)).order(:id).all.should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
specify "should fetch correctly with a limit and offset in an IN subselect" do
|
|
155
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(2, 0)).all.should == [{:id=>1, :number=>10}]
|
|
156
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(2, 1)).all.should == []
|
|
157
|
+
@ds.insert(:number=>20)
|
|
158
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(1, 1)).all.should == [{:id=>2, :number=>20}]
|
|
159
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(2, 0)).order(:id).all.should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
|
160
|
+
@ds.where(:id=>@ds.select(:id).order(:id).limit(2, 1)).all.should == [{:id=>2, :number=>20}]
|
|
161
|
+
end
|
|
162
|
+
|
|
86
163
|
specify "should alias columns correctly" do
|
|
87
164
|
@ds.select(:id___x, :number___n).first.should == {:x=>1, :n=>10}
|
|
88
165
|
end
|
|
166
|
+
|
|
167
|
+
specify "should handle true/false properly" do
|
|
168
|
+
@ds.filter(Sequel::TRUE).select_map(:number).should == [10]
|
|
169
|
+
@ds.filter(Sequel::FALSE).select_map(:number).should == []
|
|
170
|
+
@ds.filter(true).select_map(:number).should == [10]
|
|
171
|
+
@ds.filter(false).select_map(:number).should == []
|
|
172
|
+
end
|
|
89
173
|
end
|
|
90
174
|
|
|
91
175
|
describe Sequel::Dataset do
|
|
@@ -95,7 +179,6 @@ describe Sequel::Dataset do
|
|
|
95
179
|
Integer :value
|
|
96
180
|
end
|
|
97
181
|
@d = INTEGRATION_DB[:test]
|
|
98
|
-
clear_sqls
|
|
99
182
|
end
|
|
100
183
|
after do
|
|
101
184
|
INTEGRATION_DB.drop_table(:test)
|
|
@@ -187,7 +270,11 @@ describe Sequel::Database do
|
|
|
187
270
|
INTEGRATION_DB.drop_table(t) rescue nil
|
|
188
271
|
INTEGRATION_DB.table_exists?(t).should == false
|
|
189
272
|
INTEGRATION_DB.create_table(t){Integer :a}
|
|
190
|
-
|
|
273
|
+
begin
|
|
274
|
+
INTEGRATION_DB.table_exists?(t).should == true
|
|
275
|
+
ensure
|
|
276
|
+
INTEGRATION_DB.drop_table(t)
|
|
277
|
+
end
|
|
191
278
|
end
|
|
192
279
|
end
|
|
193
280
|
|
|
@@ -251,18 +338,17 @@ end
|
|
|
251
338
|
|
|
252
339
|
describe "Simple Dataset operations in transactions" do
|
|
253
340
|
before do
|
|
254
|
-
INTEGRATION_DB.create_table!(:
|
|
341
|
+
INTEGRATION_DB.create_table!(:items) do
|
|
255
342
|
primary_key :id
|
|
256
343
|
integer :number
|
|
257
344
|
end
|
|
258
|
-
@ds = INTEGRATION_DB[:
|
|
259
|
-
clear_sqls
|
|
345
|
+
@ds = INTEGRATION_DB[:items]
|
|
260
346
|
end
|
|
261
347
|
after do
|
|
262
|
-
INTEGRATION_DB.drop_table(:
|
|
348
|
+
INTEGRATION_DB.drop_table(:items)
|
|
263
349
|
end
|
|
264
350
|
|
|
265
|
-
cspecify "should insert correctly with a primary key specified inside a transaction", :mssql do
|
|
351
|
+
cspecify "should insert correctly with a primary key specified inside a transaction", :db2, :mssql do
|
|
266
352
|
INTEGRATION_DB.transaction do
|
|
267
353
|
@ds.insert(:id=>100, :number=>20)
|
|
268
354
|
@ds.count.should == 1
|
|
@@ -293,7 +379,6 @@ describe "Dataset UNION, EXCEPT, and INTERSECT" do
|
|
|
293
379
|
@ds2 = INTEGRATION_DB[:i2]
|
|
294
380
|
@ds2.insert(:number=>10)
|
|
295
381
|
@ds2.insert(:number=>30)
|
|
296
|
-
clear_sqls
|
|
297
382
|
end
|
|
298
383
|
|
|
299
384
|
specify "should give the correct results for simple UNION, EXCEPT, and INTERSECT" do
|
|
@@ -359,7 +444,7 @@ end
|
|
|
359
444
|
|
|
360
445
|
if INTEGRATION_DB.dataset.supports_cte?
|
|
361
446
|
describe "Common Table Expressions" do
|
|
362
|
-
before do
|
|
447
|
+
before(:all) do
|
|
363
448
|
@db = INTEGRATION_DB
|
|
364
449
|
@db.create_table!(:i1){Integer :id; Integer :parent_id}
|
|
365
450
|
@ds = @db[:i1]
|
|
@@ -370,7 +455,7 @@ if INTEGRATION_DB.dataset.supports_cte?
|
|
|
370
455
|
@ds.insert(:id=>5, :parent_id=>3)
|
|
371
456
|
@ds.insert(:id=>6, :parent_id=>5)
|
|
372
457
|
end
|
|
373
|
-
after do
|
|
458
|
+
after(:all) do
|
|
374
459
|
@db.drop_table(:i1)
|
|
375
460
|
end
|
|
376
461
|
|
|
@@ -378,7 +463,7 @@ if INTEGRATION_DB.dataset.supports_cte?
|
|
|
378
463
|
@db[:t].with(:t, @ds.filter(:parent_id=>nil).select(:id)).order(:id).map(:id).should == [1, 2]
|
|
379
464
|
end
|
|
380
465
|
|
|
381
|
-
|
|
466
|
+
cspecify "should give correct results for recursive WITH", :db2 do
|
|
382
467
|
ds = @db[:t].select(:i___id, :pi___parent_id).with_recursive(:t, @ds.filter(:parent_id=>nil), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
|
|
383
468
|
ds.all.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>nil, :id=>2}, {:parent_id=>1, :id=>3}, {:parent_id=>1, :id=>4}, {:parent_id=>3, :id=>5}, {:parent_id=>5, :id=>6}]
|
|
384
469
|
ps = @db[:t].select(:i___id, :pi___parent_id).with_recursive(:t, @ds.filter(:parent_id=>:$n), @ds.join(:t, :i=>:parent_id).filter(:t__i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi]).prepare(:select, :cte_sel)
|
|
@@ -391,12 +476,116 @@ if INTEGRATION_DB.dataset.supports_cte?
|
|
|
391
476
|
@ds.inner_join(@db[:t].with(:t, @ds.filter(:parent_id=>nil)), :id => :id).select(:i1__id).order(:i1__id).map(:id).should == [1,2]
|
|
392
477
|
@db[:t].with(:t, @ds).inner_join(@db[:s].with(:s, @ds.filter(:parent_id=>nil)), :id => :id).select(:t__id).order(:t__id).map(:id).should == [1,2]
|
|
393
478
|
end
|
|
479
|
+
|
|
480
|
+
specify "should support a subselect in the FROM clause with a CTE" do
|
|
481
|
+
@ds.from(@db[:t].with(:t, @ds)).select_order_map(:id).should == [1,2,3,4,5,6]
|
|
482
|
+
@db[:t].with(:t, @ds).from_self.select_order_map(:id).should == [1,2,3,4,5,6]
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
specify "should support using a CTE inside a CTE" do
|
|
486
|
+
@db[:s].with(:s, @db[:t].with(:t, @ds)).select_order_map(:id).should == [1,2,3,4,5,6]
|
|
487
|
+
@db[:s].with_recursive(:s, @db[:t].with(:t, @ds), @db[:t2].with(:t2, @ds)).select_order_map(:id).should == [1,1,2,2,3,3,4,4,5,5,6,6]
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
specify "should support using a CTE inside UNION/EXCEPT/INTERSECT" do
|
|
491
|
+
@ds.union(@db[:t].with(:t, @ds)).select_order_map(:id).should == [1,2,3,4,5,6]
|
|
492
|
+
if @ds.supports_intersect_except?
|
|
493
|
+
@ds.intersect(@db[:t].with(:t, @ds)).select_order_map(:id).should == [1,2,3,4,5,6]
|
|
494
|
+
@ds.except(@db[:t].with(:t, @ds)).select_order_map(:id).should == []
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
if INTEGRATION_DB.dataset.supports_cte?(:update) # Assume INSERT and DELETE support as well
|
|
501
|
+
describe "Common Table Expressions in INSERT/UPDATE/DELETE" do
|
|
502
|
+
before do
|
|
503
|
+
@db = INTEGRATION_DB
|
|
504
|
+
@db.create_table!(:i1){Integer :id}
|
|
505
|
+
@ds = @db[:i1]
|
|
506
|
+
@ds2 = @ds.with(:t, @ds)
|
|
507
|
+
@ds.insert(:id=>1)
|
|
508
|
+
@ds.insert(:id=>2)
|
|
509
|
+
end
|
|
510
|
+
after do
|
|
511
|
+
@db.drop_table(:i1)
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
specify "should give correct results for WITH" do
|
|
515
|
+
@ds2.insert(@db[:t])
|
|
516
|
+
@ds.select_order_map(:id).should == [1, 1, 2, 2]
|
|
517
|
+
@ds2.filter(:id=>@db[:t].select{max(id)}).update(:id=>:id+1)
|
|
518
|
+
@ds.select_order_map(:id).should == [1, 1, 3, 3]
|
|
519
|
+
@ds2.filter(:id=>@db[:t].select{max(id)}).delete
|
|
520
|
+
@ds.select_order_map(:id).should == [1, 1]
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
if INTEGRATION_DB.dataset.supports_returning?(:insert)
|
|
526
|
+
describe "RETURNING clauses in INSERT" do
|
|
527
|
+
before do
|
|
528
|
+
@db = INTEGRATION_DB
|
|
529
|
+
@db.create_table!(:i1){Integer :id; Integer :foo}
|
|
530
|
+
@ds = @db[:i1]
|
|
531
|
+
end
|
|
532
|
+
after do
|
|
533
|
+
@db.drop_table(:i1)
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
specify "should give correct results" do
|
|
537
|
+
h = {}
|
|
538
|
+
@ds.returning(:foo).insert(1, 2){|r| h = r}
|
|
539
|
+
h.should == {:foo=>2}
|
|
540
|
+
@ds.returning(:id).insert(3, 4){|r| h = r}
|
|
541
|
+
h.should == {:id=>3}
|
|
542
|
+
@ds.returning.insert(5, 6){|r| h = r}
|
|
543
|
+
h.should == {:id=>5, :foo=>6}
|
|
544
|
+
@ds.returning(:id___foo, :foo___id).insert(7, 8){|r| h = r}
|
|
545
|
+
h.should == {:id=>8, :foo=>7}
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
if INTEGRATION_DB.dataset.supports_returning?(:update) # Assume DELETE support as well
|
|
551
|
+
describe "RETURNING clauses in UPDATE/DELETE" do
|
|
552
|
+
before do
|
|
553
|
+
@db = INTEGRATION_DB
|
|
554
|
+
@db.create_table!(:i1){Integer :id; Integer :foo}
|
|
555
|
+
@ds = @db[:i1]
|
|
556
|
+
@ds.insert(1, 2)
|
|
557
|
+
end
|
|
558
|
+
after do
|
|
559
|
+
@db.drop_table(:i1)
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
specify "should give correct results" do
|
|
563
|
+
h = []
|
|
564
|
+
@ds.returning(:foo).update(:id=>:id+1, :foo=>:foo*2){|r| h << r}
|
|
565
|
+
h.should == [{:foo=>4}]
|
|
566
|
+
h.clear
|
|
567
|
+
@ds.returning(:id).update(:id=>:id+1, :foo=>:foo*2){|r| h << r}
|
|
568
|
+
h.should == [{:id=>3}]
|
|
569
|
+
h.clear
|
|
570
|
+
@ds.returning.update(:id=>:id+1, :foo=>:foo*2){|r| h << r}
|
|
571
|
+
h.should == [{:id=>4, :foo=>16}]
|
|
572
|
+
h.clear
|
|
573
|
+
@ds.returning(:id___foo, :foo___id).update(:id=>:id+1, :foo=>:foo*2){|r| h << r}
|
|
574
|
+
h.should == [{:id=>32, :foo=>5}]
|
|
575
|
+
h.clear
|
|
576
|
+
|
|
577
|
+
@ds.returning.delete{|r| h << r}
|
|
578
|
+
h.should == [{:id=>5, :foo=>32}]
|
|
579
|
+
h.clear
|
|
580
|
+
@ds.returning.delete{|r| h << r}
|
|
581
|
+
h.should == []
|
|
582
|
+
end
|
|
394
583
|
end
|
|
395
584
|
end
|
|
396
585
|
|
|
397
586
|
if INTEGRATION_DB.dataset.supports_window_functions?
|
|
398
587
|
describe "Window Functions" do
|
|
399
|
-
before do
|
|
588
|
+
before(:all) do
|
|
400
589
|
@db = INTEGRATION_DB
|
|
401
590
|
@db.create_table!(:i1){Integer :id; Integer :group_id; Integer :amount}
|
|
402
591
|
@ds = @db[:i1].order(:id)
|
|
@@ -407,7 +596,7 @@ if INTEGRATION_DB.dataset.supports_window_functions?
|
|
|
407
596
|
@ds.insert(:id=>5, :group_id=>2, :amount=>10000)
|
|
408
597
|
@ds.insert(:id=>6, :group_id=>2, :amount=>100000)
|
|
409
598
|
end
|
|
410
|
-
after do
|
|
599
|
+
after(:all) do
|
|
411
600
|
@db.drop_table(:i1)
|
|
412
601
|
end
|
|
413
602
|
|
|
@@ -435,21 +624,13 @@ if INTEGRATION_DB.dataset.supports_window_functions?
|
|
|
435
624
|
cspecify "should give correct results for aggregate window functions with frames", :mssql do
|
|
436
625
|
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:all){}.as(:sum)}.all.should ==
|
|
437
626
|
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
|
438
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:all){}.as(:sum)}.all.should ==
|
|
439
|
-
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
|
440
627
|
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:all){}.as(:sum)}.all.should ==
|
|
441
628
|
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
|
442
|
-
@ds.select(:id){sum(:over, :args=>amount, :frame=>:all){}.as(:sum)}.all.should ==
|
|
443
|
-
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
|
444
629
|
|
|
445
630
|
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:rows){}.as(:sum)}.all.should ==
|
|
446
631
|
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
|
447
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:rows){}.as(:sum)}.all.should ==
|
|
448
|
-
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
|
449
632
|
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:rows){}.as(:sum)}.all.should ==
|
|
450
633
|
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
|
451
|
-
@ds.select(:id){sum(:over, :args=>amount, :frame=>:rows){}.as(:sum)}.all.should ==
|
|
452
|
-
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
|
453
634
|
end
|
|
454
635
|
end
|
|
455
636
|
end
|
|
@@ -471,10 +652,10 @@ describe Sequel::SQL::Constants do
|
|
|
471
652
|
@c2 = proc{|v| v.is_a?(Date) ? v : Date.parse(v) }
|
|
472
653
|
end
|
|
473
654
|
after do
|
|
474
|
-
@db.drop_table(:constants)
|
|
655
|
+
@db.drop_table(:constants) if @db.table_exists?(:constants)
|
|
475
656
|
end
|
|
476
657
|
|
|
477
|
-
cspecify "should have working CURRENT_DATE", [:odbc, :mssql], [:jdbc, :sqlite] do
|
|
658
|
+
cspecify "should have working CURRENT_DATE", [:odbc, :mssql], [:jdbc, :sqlite], :oracle do
|
|
478
659
|
@db.create_table!(:constants){Date :d}
|
|
479
660
|
@ds.insert(:d=>Sequel::CURRENT_DATE)
|
|
480
661
|
d = @c2[@ds.get(:d)]
|
|
@@ -485,26 +666,27 @@ describe Sequel::SQL::Constants do
|
|
|
485
666
|
cspecify "should have working CURRENT_TIME", [:do, :mysql], [:jdbc, :sqlite], [:mysql2] do
|
|
486
667
|
@db.create_table!(:constants){Time :t, :only_time=>true}
|
|
487
668
|
@ds.insert(:t=>Sequel::CURRENT_TIME)
|
|
488
|
-
(Time.now - @c[@ds.get(:t)]).should be_within(
|
|
669
|
+
(Time.now - @c[@ds.get(:t)]).should be_within(2).of(0)
|
|
489
670
|
end
|
|
490
671
|
|
|
491
672
|
cspecify "should have working CURRENT_TIMESTAMP", [:jdbc, :sqlite] do
|
|
492
673
|
@db.create_table!(:constants){DateTime :ts}
|
|
493
674
|
@ds.insert(:ts=>Sequel::CURRENT_TIMESTAMP)
|
|
494
|
-
(Time.now - @c[@ds.get(:ts)]).should be_within(
|
|
675
|
+
(Time.now - @c[@ds.get(:ts)]).should be_within(2).of(0)
|
|
495
676
|
end
|
|
496
677
|
end
|
|
497
678
|
|
|
498
679
|
describe "Sequel::Dataset#import and #multi_insert" do
|
|
499
|
-
before do
|
|
680
|
+
before(:all) do
|
|
500
681
|
@db = INTEGRATION_DB
|
|
501
682
|
@db.create_table!(:imp){Integer :i}
|
|
502
|
-
@db.create_table!(:exp2){Integer :i}
|
|
503
683
|
@ids = @db[:imp].order(:i)
|
|
504
|
-
@eds = @db[:exp2]
|
|
505
684
|
end
|
|
506
|
-
|
|
507
|
-
@
|
|
685
|
+
before do
|
|
686
|
+
@ids.delete
|
|
687
|
+
end
|
|
688
|
+
after(:all) do
|
|
689
|
+
@db.drop_table(:imp)
|
|
508
690
|
end
|
|
509
691
|
|
|
510
692
|
it "should import with multi_insert and an array of hashes" do
|
|
@@ -518,9 +700,11 @@ describe "Sequel::Dataset#import and #multi_insert" do
|
|
|
518
700
|
end
|
|
519
701
|
|
|
520
702
|
it "should import with a dataset" do
|
|
521
|
-
@
|
|
522
|
-
@
|
|
703
|
+
@db.create_table!(:exp2){Integer :i}
|
|
704
|
+
@db[:exp2].import([:i], [[10], [20]])
|
|
705
|
+
@ids.import([:i], @db[:exp2])
|
|
523
706
|
@ids.all.should == [{:i=>10}, {:i=>20}]
|
|
707
|
+
@db.drop_table(:exp2)
|
|
524
708
|
end
|
|
525
709
|
|
|
526
710
|
it "should have import work with the :slice_size option" do
|
|
@@ -535,13 +719,65 @@ describe "Sequel::Dataset#import and #multi_insert" do
|
|
|
535
719
|
end
|
|
536
720
|
end
|
|
537
721
|
|
|
538
|
-
describe "Sequel::Dataset
|
|
722
|
+
describe "Sequel::Dataset#import and #multi_insert :return=>:primary_key " do
|
|
539
723
|
before do
|
|
724
|
+
@db = INTEGRATION_DB
|
|
725
|
+
@db.create_table!(:imp){primary_key :id; Integer :i}
|
|
726
|
+
@ds = @db[:imp]
|
|
727
|
+
end
|
|
728
|
+
after do
|
|
729
|
+
@db.drop_table(:imp)
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
specify "should return primary key values " do
|
|
733
|
+
@ds.multi_insert([{:i=>10}, {:i=>20}, {:i=>30}], :return=>:primary_key).should == [1, 2, 3]
|
|
734
|
+
@ds.import([:i], [[40], [50], [60]], :return=>:primary_key).should == [4, 5, 6]
|
|
735
|
+
@ds.order(:id).map([:id, :i]).should == [[1, 10], [2, 20], [3, 30], [4, 40], [5, 50], [6, 60]]
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
specify "should return primary key values when :slice is used" do
|
|
739
|
+
@ds.multi_insert([{:i=>10}, {:i=>20}, {:i=>30}], :return=>:primary_key, :slice=>2).should == [1, 2, 3]
|
|
740
|
+
@ds.import([:i], [[40], [50], [60]], :return=>:primary_key, :slice=>2).should == [4, 5, 6]
|
|
741
|
+
@ds.order(:id).map([:id, :i]).should == [[1, 10], [2, 20], [3, 30], [4, 40], [5, 50], [6, 60]]
|
|
742
|
+
end
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
describe "Sequel::Dataset convenience methods" do
|
|
746
|
+
before(:all) do
|
|
747
|
+
@db = INTEGRATION_DB
|
|
748
|
+
@db.create_table!(:a){Integer :a; Integer :b; Integer :c}
|
|
749
|
+
@ds = @db[:a]
|
|
750
|
+
@ds.insert(1, 3, 5)
|
|
751
|
+
@ds.insert(1, 3, 6)
|
|
752
|
+
@ds.insert(1, 4, 5)
|
|
753
|
+
@ds.insert(2, 3, 5)
|
|
754
|
+
@ds.insert(2, 4, 6)
|
|
755
|
+
end
|
|
756
|
+
after(:all) do
|
|
757
|
+
@db.drop_table(:a)
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
it "#group_rollup should include hierarchy of groupings" do
|
|
761
|
+
@ds.group_by(:a).group_rollup.select_map([:a, :sum.sql_function(:b).cast(Integer).as(:b), :sum.sql_function(:c).cast(Integer).as(:c)]).sort_by{|x| x.inspect}.should == [[1, 10, 16], [2, 7, 11], [nil, 17, 27]]
|
|
762
|
+
@ds.group_by(:a, :b).group_rollup.select_map([:a, :b, :sum.sql_function(:c).cast(Integer).as(:c)]).sort_by{|x| x.inspect}.should == [[1, 3, 11], [1, 4, 5], [1, nil, 16], [2, 3, 5], [2, 4, 6], [2, nil, 11], [nil, nil, 27]]
|
|
763
|
+
end if INTEGRATION_DB.dataset.supports_group_rollup?
|
|
764
|
+
|
|
765
|
+
it "#group_cube should include all combinations of groupings" do
|
|
766
|
+
@ds.group_by(:a).group_cube.select_map([:a, :sum.sql_function(:b).cast(Integer).as(:b), :sum.sql_function(:c).cast(Integer).as(:c)]).sort_by{|x| x.inspect}.should == [[1, 10, 16], [2, 7, 11], [nil, 17, 27]]
|
|
767
|
+
@ds.group_by(:a, :b).group_cube.select_map([:a, :b, :sum.sql_function(:c).cast(Integer).as(:c)]).sort_by{|x| x.inspect}.should == [[1, 3, 11], [1, 4, 5], [1, nil, 16], [2, 3, 5], [2, 4, 6], [2, nil, 11], [nil, 3, 16], [nil, 4, 11], [nil, nil, 27]]
|
|
768
|
+
end if INTEGRATION_DB.dataset.supports_group_cube?
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
describe "Sequel::Dataset convenience methods" do
|
|
772
|
+
before(:all) do
|
|
540
773
|
@db = INTEGRATION_DB
|
|
541
774
|
@db.create_table!(:a){Integer :a; Integer :b}
|
|
542
775
|
@ds = @db[:a].order(:a)
|
|
543
776
|
end
|
|
544
|
-
|
|
777
|
+
before do
|
|
778
|
+
@ds.delete
|
|
779
|
+
end
|
|
780
|
+
after(:all) do
|
|
545
781
|
@db.drop_table(:a)
|
|
546
782
|
end
|
|
547
783
|
|
|
@@ -557,6 +793,22 @@ describe "Sequel::Dataset convenience methods" do
|
|
|
557
793
|
@ds.empty?.should == false
|
|
558
794
|
end
|
|
559
795
|
|
|
796
|
+
it "#empty? should work correctly for datasets with limits" do
|
|
797
|
+
ds = @ds.limit(1)
|
|
798
|
+
ds.empty?.should == true
|
|
799
|
+
ds.insert(20, 10)
|
|
800
|
+
ds.empty?.should == false
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
it "#empty? should work correctly for datasets with limits and offsets" do
|
|
804
|
+
ds = @ds.limit(1, 1)
|
|
805
|
+
ds.empty?.should == true
|
|
806
|
+
ds.insert(20, 10)
|
|
807
|
+
ds.empty?.should == true
|
|
808
|
+
ds.insert(20, 10)
|
|
809
|
+
ds.empty?.should == false
|
|
810
|
+
end
|
|
811
|
+
|
|
560
812
|
it "#group_and_count should return a grouping by count" do
|
|
561
813
|
@ds.group_and_count(:a).order(:count).all.should == []
|
|
562
814
|
@ds.insert(20, 10)
|
|
@@ -577,7 +829,7 @@ describe "Sequel::Dataset convenience methods" do
|
|
|
577
829
|
@ds.group_and_count(:a___c).order(:count).all.each{|h| h[:count] = h[:count].to_i}.should == [{:c=>30, :count=>1}, {:c=>20, :count=>2}]
|
|
578
830
|
end
|
|
579
831
|
|
|
580
|
-
|
|
832
|
+
specify "#range should return the range between the maximum and minimum values" do
|
|
581
833
|
@ds = @ds.unordered
|
|
582
834
|
@ds.insert(20, 10)
|
|
583
835
|
@ds.insert(30, 10)
|
|
@@ -595,12 +847,15 @@ describe "Sequel::Dataset convenience methods" do
|
|
|
595
847
|
end
|
|
596
848
|
|
|
597
849
|
describe "Sequel::Dataset main SQL methods" do
|
|
598
|
-
before do
|
|
850
|
+
before(:all) do
|
|
599
851
|
@db = INTEGRATION_DB
|
|
600
852
|
@db.create_table!(:a){Integer :a; Integer :b}
|
|
601
853
|
@ds = @db[:a].order(:a)
|
|
602
854
|
end
|
|
603
|
-
|
|
855
|
+
before do
|
|
856
|
+
@ds.delete
|
|
857
|
+
end
|
|
858
|
+
after(:all) do
|
|
604
859
|
@db.drop_table(:a)
|
|
605
860
|
end
|
|
606
861
|
|
|
@@ -625,6 +880,23 @@ describe "Sequel::Dataset main SQL methods" do
|
|
|
625
880
|
@ds.filter(:a=>20).or(:b=>15).all.should == [{:a=>20, :b=>30}]
|
|
626
881
|
@ds.filter(:a=>10).or(:b=>15).all.should == []
|
|
627
882
|
end
|
|
883
|
+
|
|
884
|
+
it "#select_group should work correctly" do
|
|
885
|
+
@ds.unordered!
|
|
886
|
+
@ds.select_group(:a).all.should == []
|
|
887
|
+
@ds.insert(20, 30)
|
|
888
|
+
@ds.select_group(:a).all.should == [{:a=>20}]
|
|
889
|
+
@ds.select_group(:b).all.should == [{:b=>30}]
|
|
890
|
+
@ds.insert(20, 40)
|
|
891
|
+
@ds.select_group(:a).all.should == [{:a=>20}]
|
|
892
|
+
@ds.order(:b).select_group(:b).all.should == [{:b=>30}, {:b=>40}]
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
it "#select_group should work correctly when aliasing" do
|
|
896
|
+
@ds.unordered!
|
|
897
|
+
@ds.insert(20, 30)
|
|
898
|
+
@ds.select_group(:b___c).all.should == [{:c=>30}]
|
|
899
|
+
end
|
|
628
900
|
|
|
629
901
|
it "#having should work correctly" do
|
|
630
902
|
@ds.unordered!
|
|
@@ -645,13 +917,92 @@ describe "Sequel::Dataset main SQL methods" do
|
|
|
645
917
|
end
|
|
646
918
|
end
|
|
647
919
|
|
|
648
|
-
describe "Sequel::Dataset
|
|
920
|
+
describe "Sequel::Dataset convenience methods" do
|
|
921
|
+
before(:all) do
|
|
922
|
+
@db = INTEGRATION_DB
|
|
923
|
+
@db.create_table!(:a){Integer :a; Integer :b; Integer :c; Integer :d}
|
|
924
|
+
@ds = @db[:a].order(:a)
|
|
925
|
+
end
|
|
649
926
|
before do
|
|
927
|
+
@ds.delete
|
|
928
|
+
@ds.insert(1, 2, 3, 4)
|
|
929
|
+
@ds.insert(5, 6, 7, 8)
|
|
930
|
+
end
|
|
931
|
+
after(:all) do
|
|
932
|
+
@db.drop_table(:a)
|
|
933
|
+
end
|
|
934
|
+
|
|
935
|
+
specify "should have working #map" do
|
|
936
|
+
@ds.map(:a).should == [1, 5]
|
|
937
|
+
@ds.map(:b).should == [2, 6]
|
|
938
|
+
@ds.map([:a, :b]).should == [[1, 2], [5, 6]]
|
|
939
|
+
end
|
|
940
|
+
|
|
941
|
+
specify "should have working #to_hash" do
|
|
942
|
+
@ds.to_hash(:a).should == {1=>{:a=>1, :b=>2, :c=>3, :d=>4}, 5=>{:a=>5, :b=>6, :c=>7, :d=>8}}
|
|
943
|
+
@ds.to_hash(:b).should == {2=>{:a=>1, :b=>2, :c=>3, :d=>4}, 6=>{:a=>5, :b=>6, :c=>7, :d=>8}}
|
|
944
|
+
@ds.to_hash([:a, :b]).should == {[1, 2]=>{:a=>1, :b=>2, :c=>3, :d=>4}, [5, 6]=>{:a=>5, :b=>6, :c=>7, :d=>8}}
|
|
945
|
+
|
|
946
|
+
@ds.to_hash(:a, :b).should == {1=>2, 5=>6}
|
|
947
|
+
@ds.to_hash([:a, :c], :b).should == {[1, 3]=>2, [5, 7]=>6}
|
|
948
|
+
@ds.to_hash(:a, [:b, :c]).should == {1=>[2, 3], 5=>[6, 7]}
|
|
949
|
+
@ds.to_hash([:a, :c], [:b, :d]).should == {[1, 3]=>[2, 4], [5, 7]=>[6, 8]}
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
specify "should have working #select_map" do
|
|
953
|
+
@ds.select_map(:a).should == [1, 5]
|
|
954
|
+
@ds.select_map(:b).should == [2, 6]
|
|
955
|
+
@ds.select_map([:a]).should == [[1], [5]]
|
|
956
|
+
@ds.select_map([:a, :b]).should == [[1, 2], [5, 6]]
|
|
957
|
+
|
|
958
|
+
@ds.select_map(:a___e).should == [1, 5]
|
|
959
|
+
@ds.select_map(:b___e).should == [2, 6]
|
|
960
|
+
@ds.select_map([:a___e, :b___f]).should == [[1, 2], [5, 6]]
|
|
961
|
+
@ds.select_map([:a__a___e, :a__b___f]).should == [[1, 2], [5, 6]]
|
|
962
|
+
@ds.select_map([:a__a.as(:e), :a__b.as(:f)]).should == [[1, 2], [5, 6]]
|
|
963
|
+
@ds.select_map([:a.qualify(:a).as(:e), :b.qualify(:a).as(:f)]).should == [[1, 2], [5, 6]]
|
|
964
|
+
@ds.select_map([:a.identifier.qualify(:a).as(:e), :b.qualify(:a).as(:f)]).should == [[1, 2], [5, 6]]
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
specify "should have working #select_order_map" do
|
|
968
|
+
@ds.select_order_map(:a).should == [1, 5]
|
|
969
|
+
@ds.select_order_map(:a__b.desc).should == [6, 2]
|
|
970
|
+
@ds.select_order_map(:a__b___e.desc).should == [6, 2]
|
|
971
|
+
@ds.select_order_map(:b.qualify(:a).as(:e)).should == [2, 6]
|
|
972
|
+
@ds.select_order_map([:a]).should == [[1], [5]]
|
|
973
|
+
@ds.select_order_map([:a.desc, :b]).should == [[5, 6], [1, 2]]
|
|
974
|
+
|
|
975
|
+
@ds.select_order_map(:a___e).should == [1, 5]
|
|
976
|
+
@ds.select_order_map(:b___e).should == [2, 6]
|
|
977
|
+
@ds.select_order_map([:a___e.desc, :b___f]).should == [[5, 6], [1, 2]]
|
|
978
|
+
@ds.select_order_map([:a__a___e.desc, :a__b___f]).should == [[5, 6], [1, 2]]
|
|
979
|
+
@ds.select_order_map([:a__a.desc, :a__b.as(:f)]).should == [[5, 6], [1, 2]]
|
|
980
|
+
@ds.select_order_map([:a.qualify(:a).desc, :b.qualify(:a).as(:f)]).should == [[5, 6], [1, 2]]
|
|
981
|
+
@ds.select_order_map([:a.identifier.qualify(:a).desc, :b.qualify(:a).as(:f)]).should == [[5, 6], [1, 2]]
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
specify "should have working #select_hash" do
|
|
985
|
+
@ds.select_hash(:a, :b).should == {1=>2, 5=>6}
|
|
986
|
+
@ds.select_hash(:a__a___e, :b).should == {1=>2, 5=>6}
|
|
987
|
+
@ds.select_hash(:a__a.as(:e), :b).should == {1=>2, 5=>6}
|
|
988
|
+
@ds.select_hash(:a.qualify(:a).as(:e), :b).should == {1=>2, 5=>6}
|
|
989
|
+
@ds.select_hash(:a.identifier.qualify(:a).as(:e), :b).should == {1=>2, 5=>6}
|
|
990
|
+
@ds.select_hash([:a, :c], :b).should == {[1, 3]=>2, [5, 7]=>6}
|
|
991
|
+
@ds.select_hash(:a, [:b, :c]).should == {1=>[2, 3], 5=>[6, 7]}
|
|
992
|
+
@ds.select_hash([:a, :c], [:b, :d]).should == {[1, 3]=>[2, 4], [5, 7]=>[6, 8]}
|
|
993
|
+
end
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
describe "Sequel::Dataset DSL support" do
|
|
997
|
+
before(:all) do
|
|
650
998
|
@db = INTEGRATION_DB
|
|
651
999
|
@db.create_table!(:a){Integer :a; Integer :b}
|
|
652
1000
|
@ds = @db[:a].order(:a)
|
|
653
1001
|
end
|
|
654
|
-
|
|
1002
|
+
before do
|
|
1003
|
+
@ds.delete
|
|
1004
|
+
end
|
|
1005
|
+
after(:all) do
|
|
655
1006
|
@db.drop_table(:a)
|
|
656
1007
|
end
|
|
657
1008
|
|
|
@@ -663,31 +1014,36 @@ describe "Sequel::Dataset DSL support" do
|
|
|
663
1014
|
@ds.get{a / b}.to_i.should == 2
|
|
664
1015
|
end
|
|
665
1016
|
|
|
666
|
-
|
|
1017
|
+
cspecify "should work with bitwise shift operators", :derby do
|
|
667
1018
|
@ds.insert(3, 2)
|
|
668
1019
|
@ds.get{a.sql_number << b}.to_i.should == 12
|
|
669
1020
|
@ds.get{a.sql_number >> b}.to_i.should == 0
|
|
1021
|
+
@ds.get{a.sql_number << b << 1}.to_i.should == 24
|
|
670
1022
|
@ds.delete
|
|
671
1023
|
@ds.insert(3, 1)
|
|
672
1024
|
@ds.get{a.sql_number << b}.to_i.should == 6
|
|
673
1025
|
@ds.get{a.sql_number >> b}.to_i.should == 1
|
|
1026
|
+
@ds.get{a.sql_number >> b >> 1}.to_i.should == 0
|
|
674
1027
|
end
|
|
675
1028
|
|
|
676
|
-
|
|
1029
|
+
cspecify "should work with bitwise AND and OR operators", :derby do
|
|
677
1030
|
@ds.insert(3, 5)
|
|
678
1031
|
@ds.get{a.sql_number | b}.to_i.should == 7
|
|
679
1032
|
@ds.get{a.sql_number & b}.to_i.should == 1
|
|
1033
|
+
@ds.get{a.sql_number | b | 8}.to_i.should == 15
|
|
1034
|
+
@ds.get{a.sql_number & b & 8}.to_i.should == 0
|
|
680
1035
|
end
|
|
681
1036
|
|
|
682
|
-
|
|
1037
|
+
specify "should work with the bitwise compliment operator" do
|
|
683
1038
|
@ds.insert(-3, 3)
|
|
684
1039
|
@ds.get{~a.sql_number}.to_i.should == 2
|
|
685
1040
|
@ds.get{~b.sql_number}.to_i.should == -4
|
|
686
1041
|
end
|
|
687
1042
|
|
|
688
|
-
cspecify "should work with the bitwise xor operator", :
|
|
1043
|
+
cspecify "should work with the bitwise xor operator", :derby do
|
|
689
1044
|
@ds.insert(3, 5)
|
|
690
1045
|
@ds.get{a.sql_number ^ b}.to_i.should == 6
|
|
1046
|
+
@ds.get{a.sql_number ^ b ^ 1}.to_i.should == 7
|
|
691
1047
|
end
|
|
692
1048
|
|
|
693
1049
|
specify "should work with inequality operators" do
|
|
@@ -778,7 +1134,7 @@ describe "Sequel::Dataset DSL support" do
|
|
|
778
1134
|
@ds.filter({15=>20}.case(0, :a) > 0).all.should == []
|
|
779
1135
|
end
|
|
780
1136
|
|
|
781
|
-
|
|
1137
|
+
specify "should work with multiple value arrays" do
|
|
782
1138
|
@ds.insert(20, 10)
|
|
783
1139
|
@ds.quote_identifiers = false
|
|
784
1140
|
@ds.filter([:a, :b]=>[[20, 10]].sql_array).all.should == [{:a=>20, :b=>10}]
|
|
@@ -847,22 +1203,36 @@ describe "SQL Extract Function" do
|
|
|
847
1203
|
@db.drop_table(:a)
|
|
848
1204
|
end
|
|
849
1205
|
|
|
850
|
-
|
|
1206
|
+
specify "should return the part of the datetime asked for" do
|
|
851
1207
|
t = Time.now
|
|
1208
|
+
def @ds.supports_timestamp_timezones?() false end
|
|
852
1209
|
@ds.insert(t)
|
|
853
1210
|
@ds.get{a.extract(:year)}.should == t.year
|
|
854
1211
|
@ds.get{a.extract(:month)}.should == t.month
|
|
855
1212
|
@ds.get{a.extract(:day)}.should == t.day
|
|
1213
|
+
@ds.get{a.extract(:hour)}.should == t.hour
|
|
1214
|
+
@ds.get{a.extract(:minute)}.should == t.min
|
|
1215
|
+
@ds.get{a.extract(:second)}.to_i.should == t.sec
|
|
856
1216
|
end
|
|
857
1217
|
end
|
|
858
1218
|
|
|
859
1219
|
describe "Dataset string methods" do
|
|
860
|
-
before do
|
|
1220
|
+
before(:all) do
|
|
861
1221
|
@db = INTEGRATION_DB
|
|
862
|
-
|
|
1222
|
+
csc = {}
|
|
1223
|
+
cic = {}
|
|
1224
|
+
csc[:collate] = @db.dataset_class::CASE_SENSITIVE_COLLATION if defined? @db.dataset_class::CASE_SENSITIVE_COLLATION
|
|
1225
|
+
cic[:collate] = @db.dataset_class::CASE_INSENSITIVE_COLLATION if defined? @db.dataset_class::CASE_INSENSITIVE_COLLATION
|
|
1226
|
+
@db.create_table!(:a) do
|
|
1227
|
+
String :a, csc
|
|
1228
|
+
String :b, cic
|
|
1229
|
+
end
|
|
863
1230
|
@ds = @db[:a].order(:a)
|
|
864
1231
|
end
|
|
865
|
-
|
|
1232
|
+
before do
|
|
1233
|
+
@ds.delete
|
|
1234
|
+
end
|
|
1235
|
+
after(:all) do
|
|
866
1236
|
@db.drop_table(:a)
|
|
867
1237
|
end
|
|
868
1238
|
|
|
@@ -877,15 +1247,15 @@ describe "Dataset string methods" do
|
|
|
877
1247
|
end
|
|
878
1248
|
|
|
879
1249
|
it "#grep should work with :all_patterns and :all_columns options" do
|
|
880
|
-
@ds.insert('foo bar', '')
|
|
1250
|
+
@ds.insert('foo bar', ' ')
|
|
881
1251
|
@ds.insert('foo d', 'bar')
|
|
882
|
-
@ds.insert('foo e', '')
|
|
883
|
-
@ds.insert('', 'bar')
|
|
1252
|
+
@ds.insert('foo e', ' ')
|
|
1253
|
+
@ds.insert(' ', 'bar')
|
|
884
1254
|
@ds.insert('foo f', 'baz')
|
|
885
1255
|
@ds.insert('foo baz', 'bar baz')
|
|
886
1256
|
@ds.insert('foo boo', 'boo foo')
|
|
887
1257
|
|
|
888
|
-
@ds.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true).all.should == [{:a=>'foo bar', :b=>''}, {:a=>'foo baz', :b=>'bar baz'}, {:a=>'foo d', :b=>'bar'}]
|
|
1258
|
+
@ds.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true).all.should == [{:a=>'foo bar', :b=>' '}, {:a=>'foo baz', :b=>'bar baz'}, {:a=>'foo d', :b=>'bar'}]
|
|
889
1259
|
@ds.grep([:a, :b], %w'%foo% %bar% %blob%', :all_patterns=>true).all.should == []
|
|
890
1260
|
|
|
891
1261
|
@ds.grep([:a, :b], %w'%bar% %foo%', :all_columns=>true).all.should == [{:a=>"foo baz", :b=>"bar baz"}, {:a=>"foo boo", :b=>"boo foo"}, {:a=>"foo d", :b=>"bar"}]
|
|
@@ -900,6 +1270,19 @@ describe "Dataset string methods" do
|
|
|
900
1270
|
@ds.filter(:a.like('foo')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
901
1271
|
@ds.filter(:a.like('bar')).all.should == []
|
|
902
1272
|
@ds.filter(:a.like('foo', 'bar')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
1273
|
+
@ds.exclude(:a.like('foo')).all.should == []
|
|
1274
|
+
@ds.exclude(:a.like('bar')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
1275
|
+
@ds.exclude(:a.like('foo', 'bar')).all.should == []
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
it "#like should be case sensitive" do
|
|
1279
|
+
@ds.insert('foo', 'bar')
|
|
1280
|
+
@ds.filter(:a.like('Foo')).all.should == []
|
|
1281
|
+
@ds.filter(:b.like('baR')).all.should == []
|
|
1282
|
+
@ds.filter(:a.like('FOO', 'BAR')).all.should == []
|
|
1283
|
+
@ds.exclude(:a.like('Foo')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
1284
|
+
@ds.exclude(:a.like('baR')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
1285
|
+
@ds.exclude(:a.like('FOO', 'BAR')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
903
1286
|
end
|
|
904
1287
|
|
|
905
1288
|
it "#ilike should return matching rows, in a case insensitive manner" do
|
|
@@ -907,17 +1290,20 @@ describe "Dataset string methods" do
|
|
|
907
1290
|
@ds.filter(:a.ilike('Foo')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
908
1291
|
@ds.filter(:a.ilike('baR')).all.should == []
|
|
909
1292
|
@ds.filter(:a.ilike('FOO', 'BAR')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
1293
|
+
@ds.exclude(:a.ilike('Foo')).all.should == []
|
|
1294
|
+
@ds.exclude(:a.ilike('baR')).all.should == [{:a=>'foo', :b=>'bar'}]
|
|
1295
|
+
@ds.exclude(:a.ilike('FOO', 'BAR')).all.should == []
|
|
910
1296
|
end
|
|
911
1297
|
|
|
912
1298
|
it "should work with strings created with sql_string_join" do
|
|
913
1299
|
@ds.insert('foo', 'bar')
|
|
914
|
-
@ds.get([:a,
|
|
915
|
-
@ds.get([
|
|
1300
|
+
@ds.get([:a, "bar"].sql_string_join).should == 'foobar'
|
|
1301
|
+
@ds.get(["foo", :b].sql_string_join(' ')).should == 'foo bar'
|
|
916
1302
|
end
|
|
917
1303
|
end
|
|
918
1304
|
|
|
919
1305
|
describe "Dataset identifier methods" do
|
|
920
|
-
before do
|
|
1306
|
+
before(:all) do
|
|
921
1307
|
class ::String
|
|
922
1308
|
def uprev
|
|
923
1309
|
upcase.reverse
|
|
@@ -925,10 +1311,12 @@ describe "Dataset identifier methods" do
|
|
|
925
1311
|
end
|
|
926
1312
|
@db = INTEGRATION_DB
|
|
927
1313
|
@db.create_table!(:a){Integer :ab}
|
|
1314
|
+
@db[:a].insert(1)
|
|
1315
|
+
end
|
|
1316
|
+
before do
|
|
928
1317
|
@ds = @db[:a].order(:ab)
|
|
929
|
-
@ds.insert(1)
|
|
930
1318
|
end
|
|
931
|
-
after do
|
|
1319
|
+
after(:all) do
|
|
932
1320
|
@db.drop_table(:a)
|
|
933
1321
|
end
|
|
934
1322
|
|
|
@@ -939,6 +1327,11 @@ describe "Dataset identifier methods" do
|
|
|
939
1327
|
@ds.first.should == {:BA=>1}
|
|
940
1328
|
end
|
|
941
1329
|
|
|
1330
|
+
it "should work with a nil identifier_output_method" do
|
|
1331
|
+
@ds.identifier_output_method = nil
|
|
1332
|
+
[{:ab=>1}, {:AB=>1}].should include(@ds.first)
|
|
1333
|
+
end
|
|
1334
|
+
|
|
942
1335
|
it "should work when not quoting identifiers" do
|
|
943
1336
|
@ds.quote_identifiers = false
|
|
944
1337
|
@ds.first.should == {:ab=>1}
|
|
@@ -946,12 +1339,15 @@ describe "Dataset identifier methods" do
|
|
|
946
1339
|
end
|
|
947
1340
|
|
|
948
1341
|
describe "Dataset defaults and overrides" do
|
|
949
|
-
before do
|
|
1342
|
+
before(:all) do
|
|
950
1343
|
@db = INTEGRATION_DB
|
|
951
1344
|
@db.create_table!(:a){Integer :a}
|
|
952
1345
|
@ds = @db[:a].order(:a)
|
|
953
1346
|
end
|
|
954
|
-
|
|
1347
|
+
before do
|
|
1348
|
+
@ds.delete
|
|
1349
|
+
end
|
|
1350
|
+
after(:all) do
|
|
955
1351
|
@db.drop_table(:a)
|
|
956
1352
|
end
|
|
957
1353
|
|