viking-sequel 3.10.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 +3134 -0
- data/COPYING +19 -0
- data/README.rdoc +723 -0
- data/Rakefile +193 -0
- data/bin/sequel +196 -0
- data/doc/advanced_associations.rdoc +644 -0
- data/doc/cheat_sheet.rdoc +218 -0
- data/doc/dataset_basics.rdoc +106 -0
- data/doc/dataset_filtering.rdoc +158 -0
- data/doc/opening_databases.rdoc +296 -0
- data/doc/prepared_statements.rdoc +104 -0
- data/doc/reflection.rdoc +84 -0
- data/doc/release_notes/1.0.txt +38 -0
- data/doc/release_notes/1.1.txt +143 -0
- data/doc/release_notes/1.3.txt +101 -0
- data/doc/release_notes/1.4.0.txt +53 -0
- data/doc/release_notes/1.5.0.txt +155 -0
- data/doc/release_notes/2.0.0.txt +298 -0
- data/doc/release_notes/2.1.0.txt +271 -0
- data/doc/release_notes/2.10.0.txt +328 -0
- data/doc/release_notes/2.11.0.txt +215 -0
- data/doc/release_notes/2.12.0.txt +534 -0
- data/doc/release_notes/2.2.0.txt +253 -0
- data/doc/release_notes/2.3.0.txt +88 -0
- data/doc/release_notes/2.4.0.txt +106 -0
- data/doc/release_notes/2.5.0.txt +137 -0
- data/doc/release_notes/2.6.0.txt +157 -0
- data/doc/release_notes/2.7.0.txt +166 -0
- data/doc/release_notes/2.8.0.txt +171 -0
- data/doc/release_notes/2.9.0.txt +97 -0
- data/doc/release_notes/3.0.0.txt +221 -0
- data/doc/release_notes/3.1.0.txt +406 -0
- data/doc/release_notes/3.10.0.txt +286 -0
- data/doc/release_notes/3.2.0.txt +268 -0
- data/doc/release_notes/3.3.0.txt +192 -0
- data/doc/release_notes/3.4.0.txt +325 -0
- data/doc/release_notes/3.5.0.txt +510 -0
- data/doc/release_notes/3.6.0.txt +366 -0
- data/doc/release_notes/3.7.0.txt +179 -0
- data/doc/release_notes/3.8.0.txt +151 -0
- data/doc/release_notes/3.9.0.txt +233 -0
- data/doc/schema.rdoc +36 -0
- data/doc/sharding.rdoc +113 -0
- data/doc/virtual_rows.rdoc +205 -0
- data/lib/sequel.rb +1 -0
- data/lib/sequel/adapters/ado.rb +90 -0
- data/lib/sequel/adapters/ado/mssql.rb +30 -0
- data/lib/sequel/adapters/amalgalite.rb +176 -0
- data/lib/sequel/adapters/db2.rb +139 -0
- data/lib/sequel/adapters/dbi.rb +113 -0
- data/lib/sequel/adapters/do.rb +188 -0
- data/lib/sequel/adapters/do/mysql.rb +49 -0
- data/lib/sequel/adapters/do/postgres.rb +91 -0
- data/lib/sequel/adapters/do/sqlite.rb +40 -0
- data/lib/sequel/adapters/firebird.rb +283 -0
- data/lib/sequel/adapters/informix.rb +77 -0
- data/lib/sequel/adapters/jdbc.rb +587 -0
- data/lib/sequel/adapters/jdbc/as400.rb +58 -0
- data/lib/sequel/adapters/jdbc/h2.rb +133 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
- data/lib/sequel/adapters/mysql.rb +421 -0
- data/lib/sequel/adapters/odbc.rb +143 -0
- data/lib/sequel/adapters/odbc/mssql.rb +42 -0
- data/lib/sequel/adapters/openbase.rb +64 -0
- data/lib/sequel/adapters/oracle.rb +131 -0
- data/lib/sequel/adapters/postgres.rb +504 -0
- data/lib/sequel/adapters/shared/mssql.rb +490 -0
- data/lib/sequel/adapters/shared/mysql.rb +498 -0
- data/lib/sequel/adapters/shared/oracle.rb +195 -0
- data/lib/sequel/adapters/shared/postgres.rb +830 -0
- data/lib/sequel/adapters/shared/progress.rb +44 -0
- data/lib/sequel/adapters/shared/sqlite.rb +389 -0
- data/lib/sequel/adapters/sqlite.rb +224 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
- data/lib/sequel/connection_pool.rb +99 -0
- data/lib/sequel/connection_pool/sharded_single.rb +84 -0
- data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
- data/lib/sequel/connection_pool/single.rb +29 -0
- data/lib/sequel/connection_pool/threaded.rb +150 -0
- data/lib/sequel/core.rb +293 -0
- data/lib/sequel/core_sql.rb +241 -0
- data/lib/sequel/database.rb +1079 -0
- data/lib/sequel/database/schema_generator.rb +327 -0
- data/lib/sequel/database/schema_methods.rb +203 -0
- data/lib/sequel/database/schema_sql.rb +320 -0
- data/lib/sequel/dataset.rb +32 -0
- data/lib/sequel/dataset/actions.rb +441 -0
- data/lib/sequel/dataset/features.rb +86 -0
- data/lib/sequel/dataset/graph.rb +254 -0
- data/lib/sequel/dataset/misc.rb +119 -0
- data/lib/sequel/dataset/mutation.rb +64 -0
- data/lib/sequel/dataset/prepared_statements.rb +227 -0
- data/lib/sequel/dataset/query.rb +709 -0
- data/lib/sequel/dataset/sql.rb +996 -0
- data/lib/sequel/exceptions.rb +51 -0
- data/lib/sequel/extensions/blank.rb +43 -0
- data/lib/sequel/extensions/inflector.rb +242 -0
- data/lib/sequel/extensions/looser_typecasting.rb +21 -0
- data/lib/sequel/extensions/migration.rb +239 -0
- data/lib/sequel/extensions/named_timezones.rb +61 -0
- data/lib/sequel/extensions/pagination.rb +100 -0
- data/lib/sequel/extensions/pretty_table.rb +82 -0
- data/lib/sequel/extensions/query.rb +52 -0
- data/lib/sequel/extensions/schema_dumper.rb +271 -0
- data/lib/sequel/extensions/sql_expr.rb +122 -0
- data/lib/sequel/extensions/string_date_time.rb +46 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
- data/lib/sequel/metaprogramming.rb +9 -0
- data/lib/sequel/model.rb +120 -0
- data/lib/sequel/model/associations.rb +1514 -0
- data/lib/sequel/model/base.rb +1069 -0
- data/lib/sequel/model/default_inflections.rb +45 -0
- data/lib/sequel/model/errors.rb +39 -0
- data/lib/sequel/model/exceptions.rb +21 -0
- data/lib/sequel/model/inflections.rb +162 -0
- data/lib/sequel/model/plugins.rb +70 -0
- data/lib/sequel/plugins/active_model.rb +59 -0
- data/lib/sequel/plugins/association_dependencies.rb +103 -0
- data/lib/sequel/plugins/association_proxies.rb +41 -0
- data/lib/sequel/plugins/boolean_readers.rb +53 -0
- data/lib/sequel/plugins/caching.rb +141 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
- data/lib/sequel/plugins/composition.rb +138 -0
- data/lib/sequel/plugins/force_encoding.rb +72 -0
- data/lib/sequel/plugins/hook_class_methods.rb +126 -0
- data/lib/sequel/plugins/identity_map.rb +116 -0
- data/lib/sequel/plugins/instance_filters.rb +98 -0
- data/lib/sequel/plugins/instance_hooks.rb +57 -0
- data/lib/sequel/plugins/lazy_attributes.rb +77 -0
- data/lib/sequel/plugins/many_through_many.rb +208 -0
- data/lib/sequel/plugins/nested_attributes.rb +206 -0
- data/lib/sequel/plugins/optimistic_locking.rb +81 -0
- data/lib/sequel/plugins/rcte_tree.rb +281 -0
- data/lib/sequel/plugins/schema.rb +66 -0
- data/lib/sequel/plugins/serialization.rb +166 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
- data/lib/sequel/plugins/subclasses.rb +45 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
- data/lib/sequel/plugins/timestamps.rb +87 -0
- data/lib/sequel/plugins/touch.rb +118 -0
- data/lib/sequel/plugins/typecast_on_load.rb +72 -0
- data/lib/sequel/plugins/validation_class_methods.rb +405 -0
- data/lib/sequel/plugins/validation_helpers.rb +223 -0
- data/lib/sequel/sql.rb +1020 -0
- data/lib/sequel/timezones.rb +161 -0
- data/lib/sequel/version.rb +12 -0
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/firebird_spec.rb +407 -0
- data/spec/adapters/informix_spec.rb +97 -0
- data/spec/adapters/mssql_spec.rb +403 -0
- data/spec/adapters/mysql_spec.rb +1019 -0
- data/spec/adapters/oracle_spec.rb +286 -0
- data/spec/adapters/postgres_spec.rb +969 -0
- data/spec/adapters/spec_helper.rb +51 -0
- data/spec/adapters/sqlite_spec.rb +432 -0
- data/spec/core/connection_pool_spec.rb +808 -0
- data/spec/core/core_sql_spec.rb +417 -0
- data/spec/core/database_spec.rb +1662 -0
- data/spec/core/dataset_spec.rb +3827 -0
- data/spec/core/expression_filters_spec.rb +595 -0
- data/spec/core/object_graph_spec.rb +296 -0
- data/spec/core/schema_generator_spec.rb +159 -0
- data/spec/core/schema_spec.rb +830 -0
- data/spec/core/spec_helper.rb +56 -0
- data/spec/core/version_spec.rb +7 -0
- data/spec/extensions/active_model_spec.rb +76 -0
- data/spec/extensions/association_dependencies_spec.rb +127 -0
- data/spec/extensions/association_proxies_spec.rb +50 -0
- data/spec/extensions/blank_spec.rb +67 -0
- data/spec/extensions/boolean_readers_spec.rb +92 -0
- data/spec/extensions/caching_spec.rb +250 -0
- data/spec/extensions/class_table_inheritance_spec.rb +252 -0
- data/spec/extensions/composition_spec.rb +194 -0
- data/spec/extensions/force_encoding_spec.rb +117 -0
- data/spec/extensions/hook_class_methods_spec.rb +470 -0
- data/spec/extensions/identity_map_spec.rb +202 -0
- data/spec/extensions/inflector_spec.rb +181 -0
- data/spec/extensions/instance_filters_spec.rb +55 -0
- data/spec/extensions/instance_hooks_spec.rb +133 -0
- data/spec/extensions/lazy_attributes_spec.rb +153 -0
- data/spec/extensions/looser_typecasting_spec.rb +39 -0
- data/spec/extensions/many_through_many_spec.rb +884 -0
- data/spec/extensions/migration_spec.rb +332 -0
- data/spec/extensions/named_timezones_spec.rb +72 -0
- data/spec/extensions/nested_attributes_spec.rb +396 -0
- data/spec/extensions/optimistic_locking_spec.rb +100 -0
- data/spec/extensions/pagination_spec.rb +99 -0
- data/spec/extensions/pretty_table_spec.rb +91 -0
- data/spec/extensions/query_spec.rb +85 -0
- data/spec/extensions/rcte_tree_spec.rb +205 -0
- data/spec/extensions/schema_dumper_spec.rb +357 -0
- data/spec/extensions/schema_spec.rb +127 -0
- data/spec/extensions/serialization_spec.rb +209 -0
- data/spec/extensions/single_table_inheritance_spec.rb +96 -0
- data/spec/extensions/spec_helper.rb +91 -0
- data/spec/extensions/sql_expr_spec.rb +89 -0
- data/spec/extensions/string_date_time_spec.rb +93 -0
- data/spec/extensions/subclasses_spec.rb +52 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
- data/spec/extensions/thread_local_timezones_spec.rb +45 -0
- data/spec/extensions/timestamps_spec.rb +150 -0
- data/spec/extensions/touch_spec.rb +155 -0
- data/spec/extensions/typecast_on_load_spec.rb +69 -0
- data/spec/extensions/validation_class_methods_spec.rb +984 -0
- data/spec/extensions/validation_helpers_spec.rb +438 -0
- data/spec/integration/associations_test.rb +281 -0
- data/spec/integration/database_test.rb +26 -0
- data/spec/integration/dataset_test.rb +963 -0
- data/spec/integration/eager_loader_test.rb +734 -0
- data/spec/integration/model_test.rb +130 -0
- data/spec/integration/plugin_test.rb +814 -0
- data/spec/integration/prepared_statement_test.rb +213 -0
- data/spec/integration/schema_test.rb +361 -0
- data/spec/integration/spec_helper.rb +73 -0
- data/spec/integration/timezone_test.rb +55 -0
- data/spec/integration/transaction_test.rb +122 -0
- data/spec/integration/type_test.rb +96 -0
- data/spec/model/association_reflection_spec.rb +175 -0
- data/spec/model/associations_spec.rb +2633 -0
- data/spec/model/base_spec.rb +418 -0
- data/spec/model/dataset_methods_spec.rb +78 -0
- data/spec/model/eager_loading_spec.rb +1391 -0
- data/spec/model/hooks_spec.rb +240 -0
- data/spec/model/inflector_spec.rb +26 -0
- data/spec/model/model_spec.rb +593 -0
- data/spec/model/plugins_spec.rb +236 -0
- data/spec/model/record_spec.rb +1500 -0
- data/spec/model/spec_helper.rb +97 -0
- data/spec/model/validations_spec.rb +153 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec_config.rb.example +10 -0
- metadata +346 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe Sequel::Database do
|
4
|
+
specify "should provide disconnect functionality" do
|
5
|
+
INTEGRATION_DB.test_connection
|
6
|
+
INTEGRATION_DB.pool.size.should == 1
|
7
|
+
INTEGRATION_DB.disconnect
|
8
|
+
INTEGRATION_DB.pool.size.should == 0
|
9
|
+
end
|
10
|
+
|
11
|
+
specify "should raise Sequel::DatabaseError on invalid SQL" do
|
12
|
+
proc{INTEGRATION_DB << "SELECT"}.should raise_error(Sequel::DatabaseError)
|
13
|
+
end
|
14
|
+
|
15
|
+
specify "should store underlying wrapped exception in Sequel::DatabaseError" do
|
16
|
+
begin
|
17
|
+
INTEGRATION_DB << "SELECT"
|
18
|
+
rescue Sequel::DatabaseError=>e
|
19
|
+
e.wrapped_exception.should be_a_kind_of(Exception)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
specify "should not have the connection pool swallow non-StandardError based exceptions" do
|
24
|
+
proc{INTEGRATION_DB.pool.hold{raise Interrupt, "test"}}.should raise_error(Interrupt)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,963 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe "Simple Dataset operations" do
|
4
|
+
before do
|
5
|
+
INTEGRATION_DB.create_table!(:items) do
|
6
|
+
primary_key :id
|
7
|
+
Integer :number
|
8
|
+
end
|
9
|
+
@ds = INTEGRATION_DB[:items]
|
10
|
+
@ds.insert(:number=>10)
|
11
|
+
clear_sqls
|
12
|
+
end
|
13
|
+
after do
|
14
|
+
INTEGRATION_DB.drop_table(:items)
|
15
|
+
end
|
16
|
+
|
17
|
+
specify "should support sequential primary keys" do
|
18
|
+
@ds << {:number=>20}
|
19
|
+
@ds << {:number=>30}
|
20
|
+
@ds.order(:number).all.should == [
|
21
|
+
{:id => 1, :number=>10},
|
22
|
+
{:id => 2, :number=>20},
|
23
|
+
{:id => 3, :number=>30} ]
|
24
|
+
end
|
25
|
+
|
26
|
+
cspecify "should insert with a primary key specified", :mssql do
|
27
|
+
@ds.insert(:id=>100, :number=>20)
|
28
|
+
@ds.count.should == 2
|
29
|
+
@ds.order(:id).all.should == [{:id=>1, :number=>10}, {:id=>100, :number=>20}]
|
30
|
+
end
|
31
|
+
|
32
|
+
specify "should have insert return primary key value" do
|
33
|
+
@ds.insert(:number=>20).should == 2
|
34
|
+
@ds.filter(:id=>2).first[:number].should == 20
|
35
|
+
end
|
36
|
+
|
37
|
+
specify "should delete correctly" do
|
38
|
+
@ds.filter(1=>1).delete.should == 1
|
39
|
+
@ds.count.should == 0
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "should update correctly" do
|
43
|
+
@ds.update(:number=>:number+1).should == 1
|
44
|
+
@ds.all.should == [{:id=>1, :number=>11}]
|
45
|
+
end
|
46
|
+
|
47
|
+
cspecify "should have update return the number of matched rows", [:mysql, :mysql], [:do, :mysql], [:ado] do
|
48
|
+
@ds.update(:number=>:number).should == 1
|
49
|
+
@ds.filter(:id=>1).update(:number=>:number).should == 1
|
50
|
+
@ds.filter(:id=>2).update(:number=>:number).should == 0
|
51
|
+
@ds.all.should == [{:id=>1, :number=>10}]
|
52
|
+
end
|
53
|
+
|
54
|
+
specify "should fetch all results correctly" do
|
55
|
+
@ds.all.should == [{:id=>1, :number=>10}]
|
56
|
+
end
|
57
|
+
|
58
|
+
specify "should fetch a single row correctly" do
|
59
|
+
@ds.first.should == {:id=>1, :number=>10}
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "should fetch correctly with a limit" do
|
63
|
+
@ds.order(:id).limit(2).all.should == [{:id=>1, :number=>10}]
|
64
|
+
@ds.insert(:number=>20)
|
65
|
+
@ds.order(:id).limit(1).all.should == [{:id=>1, :number=>10}]
|
66
|
+
@ds.order(:id).limit(2).all.should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
67
|
+
end
|
68
|
+
|
69
|
+
specify "should fetch correctly with a limit and offset" do
|
70
|
+
@ds.order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10}]
|
71
|
+
@ds.order(:id).limit(2, 1).all.should == []
|
72
|
+
@ds.insert(:number=>20)
|
73
|
+
@ds.order(:id).limit(1, 1).all.should == [{:id=>2, :number=>20}]
|
74
|
+
@ds.order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
75
|
+
@ds.order(:id).limit(2, 1).all.should == [{:id=>2, :number=>20}]
|
76
|
+
end
|
77
|
+
|
78
|
+
cspecify "should fetch correctly with a limit and offset without an order", :mssql do
|
79
|
+
@ds.limit(2, 1).all.should == []
|
80
|
+
end
|
81
|
+
|
82
|
+
specify "should alias columns correctly" do
|
83
|
+
@ds.select(:id___x, :number___n).first.should == {:x=>1, :n=>10}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe Sequel::Dataset do
|
88
|
+
before do
|
89
|
+
INTEGRATION_DB.create_table!(:test) do
|
90
|
+
String :name
|
91
|
+
Integer :value
|
92
|
+
end
|
93
|
+
@d = INTEGRATION_DB[:test]
|
94
|
+
clear_sqls
|
95
|
+
end
|
96
|
+
after do
|
97
|
+
INTEGRATION_DB.drop_table(:test)
|
98
|
+
end
|
99
|
+
|
100
|
+
specify "should return the correct record count" do
|
101
|
+
@d.count.should == 0
|
102
|
+
@d << {:name => 'abc', :value => 123}
|
103
|
+
@d << {:name => 'abc', :value => 456}
|
104
|
+
@d << {:name => 'def', :value => 789}
|
105
|
+
@d.count.should == 3
|
106
|
+
end
|
107
|
+
|
108
|
+
specify "should handle aggregate methods on limited datasets correctly" do
|
109
|
+
@d << {:name => 'abc', :value => 6}
|
110
|
+
@d << {:name => 'bcd', :value => 12}
|
111
|
+
@d << {:name => 'def', :value => 18}
|
112
|
+
@d = @d.order(:name).limit(2)
|
113
|
+
@d.count.should == 2
|
114
|
+
@d.avg(:value).to_i.should == 9
|
115
|
+
@d.min(:value).to_i.should == 6
|
116
|
+
@d.reverse.min(:value).to_i.should == 12
|
117
|
+
@d.max(:value).to_i.should == 12
|
118
|
+
@d.sum(:value).to_i.should == 18
|
119
|
+
@d.interval(:value).to_i.should == 6
|
120
|
+
end
|
121
|
+
|
122
|
+
specify "should return the correct records" do
|
123
|
+
@d.to_a.should == []
|
124
|
+
@d << {:name => 'abc', :value => 123}
|
125
|
+
@d << {:name => 'abc', :value => 456}
|
126
|
+
@d << {:name => 'def', :value => 789}
|
127
|
+
|
128
|
+
@d.order(:value).to_a.should == [
|
129
|
+
{:name => 'abc', :value => 123},
|
130
|
+
{:name => 'abc', :value => 456},
|
131
|
+
{:name => 'def', :value => 789}
|
132
|
+
]
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "should update records correctly" do
|
136
|
+
@d << {:name => 'abc', :value => 123}
|
137
|
+
@d << {:name => 'abc', :value => 456}
|
138
|
+
@d << {:name => 'def', :value => 789}
|
139
|
+
@d.filter(:name => 'abc').update(:value => 530)
|
140
|
+
@d[:name => 'def'][:value].should == 789
|
141
|
+
@d.filter(:value => 530).count.should == 2
|
142
|
+
end
|
143
|
+
|
144
|
+
specify "should delete records correctly" do
|
145
|
+
@d << {:name => 'abc', :value => 123}
|
146
|
+
@d << {:name => 'abc', :value => 456}
|
147
|
+
@d << {:name => 'def', :value => 789}
|
148
|
+
@d.filter(:name => 'abc').delete
|
149
|
+
@d.count.should == 1
|
150
|
+
@d.first[:name].should == 'def'
|
151
|
+
end
|
152
|
+
|
153
|
+
specify "should be able to truncate the table" do
|
154
|
+
@d << {:name => 'abc', :value => 123}
|
155
|
+
@d << {:name => 'abc', :value => 456}
|
156
|
+
@d << {:name => 'def', :value => 789}
|
157
|
+
@d.count.should == 3
|
158
|
+
@d.truncate.should == nil
|
159
|
+
@d.count.should == 0
|
160
|
+
end
|
161
|
+
|
162
|
+
specify "should be able to literalize booleans" do
|
163
|
+
proc {@d.literal(true)}.should_not raise_error
|
164
|
+
proc {@d.literal(false)}.should_not raise_error
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe Sequel::Database do
|
169
|
+
specify "should correctly escape strings" do
|
170
|
+
INTEGRATION_DB.get("\\dingo".as(:a)) == "\\dingo"
|
171
|
+
end
|
172
|
+
|
173
|
+
specify "should correctly escape strings with quotes" do
|
174
|
+
INTEGRATION_DB.get("\\'dingo".as(:a)) == "\\'dingo"
|
175
|
+
end
|
176
|
+
|
177
|
+
specify "should properly escape binary data" do
|
178
|
+
INTEGRATION_DB.get("\1\2\3".to_sequel_blob.as(:a)) == "\1\2\3"
|
179
|
+
end
|
180
|
+
|
181
|
+
specify "should have a working table_exists?" do
|
182
|
+
t = :basdfdsafsaddsaf
|
183
|
+
INTEGRATION_DB.drop_table(t) rescue nil
|
184
|
+
INTEGRATION_DB.table_exists?(t).should == false
|
185
|
+
INTEGRATION_DB.create_table(t){Integer :a}
|
186
|
+
INTEGRATION_DB.table_exists?(t).should == true
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context Sequel::Dataset do
|
191
|
+
before do
|
192
|
+
INTEGRATION_DB.create_table! :items do
|
193
|
+
primary_key :id
|
194
|
+
Integer :value
|
195
|
+
end
|
196
|
+
@d = INTEGRATION_DB[:items]
|
197
|
+
@d << {:value => 123}
|
198
|
+
@d << {:value => 456}
|
199
|
+
@d << {:value => 789}
|
200
|
+
end
|
201
|
+
after do
|
202
|
+
INTEGRATION_DB.drop_table(:items)
|
203
|
+
end
|
204
|
+
|
205
|
+
specify "should correctly return avg" do
|
206
|
+
@d.avg(:value).to_i.should == 456
|
207
|
+
end
|
208
|
+
|
209
|
+
specify "should correctly return sum" do
|
210
|
+
@d.sum(:value).to_i.should == 1368
|
211
|
+
end
|
212
|
+
|
213
|
+
specify "should correctly return max" do
|
214
|
+
@d.max(:value).to_i.should == 789
|
215
|
+
end
|
216
|
+
|
217
|
+
specify "should correctly return min" do
|
218
|
+
@d.min(:value).to_i.should == 123
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe "Simple Dataset operations" do
|
223
|
+
before do
|
224
|
+
INTEGRATION_DB.create_table!(:items) do
|
225
|
+
Integer :number
|
226
|
+
TrueClass :flag
|
227
|
+
end
|
228
|
+
@ds = INTEGRATION_DB[:items]
|
229
|
+
end
|
230
|
+
after do
|
231
|
+
INTEGRATION_DB.drop_table(:items)
|
232
|
+
end
|
233
|
+
|
234
|
+
specify "should deal with boolean conditions correctly" do
|
235
|
+
@ds.insert(:number=>1, :flag=>true)
|
236
|
+
@ds.insert(:number=>2, :flag=>false)
|
237
|
+
@ds.insert(:number=>3, :flag=>nil)
|
238
|
+
@ds.order!(:number)
|
239
|
+
@ds.filter(:flag=>true).map(:number).should == [1]
|
240
|
+
@ds.filter(:flag=>false).map(:number).should == [2]
|
241
|
+
@ds.filter(:flag=>nil).map(:number).should == [3]
|
242
|
+
@ds.exclude(:flag=>true).map(:number).should == [2, 3]
|
243
|
+
@ds.exclude(:flag=>false).map(:number).should == [1, 3]
|
244
|
+
@ds.exclude(:flag=>nil).map(:number).should == [1, 2]
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "Simple Dataset operations in transactions" do
|
249
|
+
before do
|
250
|
+
INTEGRATION_DB.create_table!(:items_insert_in_transaction) do
|
251
|
+
primary_key :id
|
252
|
+
integer :number
|
253
|
+
end
|
254
|
+
@ds = INTEGRATION_DB[:items_insert_in_transaction]
|
255
|
+
clear_sqls
|
256
|
+
end
|
257
|
+
after do
|
258
|
+
INTEGRATION_DB.drop_table(:items_insert_in_transaction)
|
259
|
+
end
|
260
|
+
|
261
|
+
cspecify "should insert correctly with a primary key specified inside a transaction", :mssql do
|
262
|
+
INTEGRATION_DB.transaction do
|
263
|
+
@ds.insert(:id=>100, :number=>20)
|
264
|
+
@ds.count.should == 1
|
265
|
+
@ds.order(:id).all.should == [{:id=>100, :number=>20}]
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
specify "should have insert return primary key value inside a transaction" do
|
270
|
+
INTEGRATION_DB.transaction do
|
271
|
+
@ds.insert(:number=>20).should == 1
|
272
|
+
@ds.count.should == 1
|
273
|
+
@ds.order(:id).all.should == [{:id=>1, :number=>20}]
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
specify "should support for_update" do
|
278
|
+
INTEGRATION_DB.transaction{@ds.for_update.all.should == []}
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "Dataset UNION, EXCEPT, and INTERSECT" do
|
283
|
+
before do
|
284
|
+
INTEGRATION_DB.create_table!(:i1){integer :number}
|
285
|
+
INTEGRATION_DB.create_table!(:i2){integer :number}
|
286
|
+
@ds1 = INTEGRATION_DB[:i1]
|
287
|
+
@ds1.insert(:number=>10)
|
288
|
+
@ds1.insert(:number=>20)
|
289
|
+
@ds2 = INTEGRATION_DB[:i2]
|
290
|
+
@ds2.insert(:number=>10)
|
291
|
+
@ds2.insert(:number=>30)
|
292
|
+
clear_sqls
|
293
|
+
end
|
294
|
+
|
295
|
+
specify "should give the correct results for simple UNION, EXCEPT, and INTERSECT" do
|
296
|
+
@ds1.union(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30'
|
297
|
+
if @ds1.supports_intersect_except?
|
298
|
+
@ds1.except(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'20'
|
299
|
+
@ds1.intersect(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'10'
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
cspecify "should give the correct results for UNION, EXCEPT, and INTERSECT when used with ordering and limits", :mssql do
|
304
|
+
@ds1.insert(:number=>8)
|
305
|
+
@ds2.insert(:number=>9)
|
306
|
+
@ds1.insert(:number=>38)
|
307
|
+
@ds2.insert(:number=>39)
|
308
|
+
|
309
|
+
@ds1.order(:number.desc).union(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'8 9 10 20 30 38 39'
|
310
|
+
@ds1.union(@ds2.order(:number.desc)).order(:number).map{|x| x[:number].to_s}.should == %w'8 9 10 20 30 38 39'
|
311
|
+
|
312
|
+
@ds1.order(:number.desc).limit(1).union(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'9 10 30 38 39'
|
313
|
+
@ds2.order(:number.desc).limit(1).union(@ds1).order(:number).map{|x| x[:number].to_s}.should == %w'8 10 20 38 39'
|
314
|
+
|
315
|
+
@ds1.union(@ds2.order(:number).limit(1)).order(:number).map{|x| x[:number].to_s}.should == %w'8 9 10 20 38'
|
316
|
+
@ds2.union(@ds1.order(:number).limit(1)).order(:number).map{|x| x[:number].to_s}.should == %w'8 9 10 30 39'
|
317
|
+
|
318
|
+
@ds1.union(@ds2).limit(2).order(:number).map{|x| x[:number].to_s}.should == %w'8 9'
|
319
|
+
@ds2.union(@ds1).order(:number.desc).limit(2).map{|x| x[:number].to_s}.should == %w'39 38'
|
320
|
+
|
321
|
+
@ds1.order(:number.desc).limit(2).union(@ds2.order(:number.desc).limit(2)).order(:number).limit(3).map{|x| x[:number].to_s}.should == %w'20 30 38'
|
322
|
+
@ds2.order(:number).limit(2).union(@ds1.order(:number).limit(2)).order(:number.desc).limit(3).map{|x| x[:number].to_s}.should == %w'10 9 8'
|
323
|
+
end
|
324
|
+
|
325
|
+
specify "should give the correct results for compound UNION, EXCEPT, and INTERSECT" do
|
326
|
+
INTEGRATION_DB.create_table!(:i3){integer :number}
|
327
|
+
@ds3 = INTEGRATION_DB[:i3]
|
328
|
+
@ds3.insert(:number=>10)
|
329
|
+
@ds3.insert(:number=>40)
|
330
|
+
|
331
|
+
@ds1.union(@ds2).union(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30 40'
|
332
|
+
@ds1.union(@ds2.union(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30 40'
|
333
|
+
if @ds1.supports_intersect_except?
|
334
|
+
@ds1.union(@ds2).except(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'20 30'
|
335
|
+
@ds1.union(@ds2.except(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30'
|
336
|
+
@ds1.union(@ds2).intersect(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 '
|
337
|
+
@ds1.union(@ds2.intersect(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20'
|
338
|
+
|
339
|
+
@ds1.except(@ds2).union(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 40'
|
340
|
+
@ds1.except(@ds2.union(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'20'
|
341
|
+
@ds1.except(@ds2).except(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'20'
|
342
|
+
@ds1.except(@ds2.except(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20'
|
343
|
+
@ds1.except(@ds2).intersect(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w''
|
344
|
+
@ds1.except(@ds2.intersect(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'20'
|
345
|
+
|
346
|
+
@ds1.intersect(@ds2).union(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 40'
|
347
|
+
@ds1.intersect(@ds2.union(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10'
|
348
|
+
@ds1.intersect(@ds2).except(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w''
|
349
|
+
@ds1.intersect(@ds2.except(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w''
|
350
|
+
@ds1.intersect(@ds2).intersect(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10'
|
351
|
+
@ds1.intersect(@ds2.intersect(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10'
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
if INTEGRATION_DB.dataset.supports_cte?
|
357
|
+
describe "Common Table Expressions" do
|
358
|
+
before do
|
359
|
+
@db = INTEGRATION_DB
|
360
|
+
@db.create_table!(:i1){Integer :id; Integer :parent_id}
|
361
|
+
@ds = @db[:i1]
|
362
|
+
@ds.insert(:id=>1)
|
363
|
+
@ds.insert(:id=>2)
|
364
|
+
@ds.insert(:id=>3, :parent_id=>1)
|
365
|
+
@ds.insert(:id=>4, :parent_id=>1)
|
366
|
+
@ds.insert(:id=>5, :parent_id=>3)
|
367
|
+
@ds.insert(:id=>6, :parent_id=>5)
|
368
|
+
end
|
369
|
+
after do
|
370
|
+
@db.drop_table(:i1)
|
371
|
+
end
|
372
|
+
|
373
|
+
specify "should give correct results for WITH" do
|
374
|
+
@db[:t].with(:t, @ds.filter(:parent_id=>nil).select(:id)).order(:id).map(:id).should == [1, 2]
|
375
|
+
end
|
376
|
+
|
377
|
+
specify "should give correct results for recursive WITH" do
|
378
|
+
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])
|
379
|
+
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}]
|
380
|
+
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)
|
381
|
+
ps.call(:n=>1).should == [{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}, {:id=>5, :parent_id=>3}, {:id=>6, :parent_id=>5}]
|
382
|
+
ps.call(:n=>3).should == [{:id=>5, :parent_id=>3}, {:id=>6, :parent_id=>5}]
|
383
|
+
ps.call(:n=>5).should == [{:id=>6, :parent_id=>5}]
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
if INTEGRATION_DB.dataset.supports_window_functions?
|
389
|
+
describe "Window Functions" do
|
390
|
+
before do
|
391
|
+
@db = INTEGRATION_DB
|
392
|
+
@db.create_table!(:i1){Integer :id; Integer :group_id; Integer :amount}
|
393
|
+
@ds = @db[:i1].order(:id)
|
394
|
+
@ds.insert(:id=>1, :group_id=>1, :amount=>1)
|
395
|
+
@ds.insert(:id=>2, :group_id=>1, :amount=>10)
|
396
|
+
@ds.insert(:id=>3, :group_id=>1, :amount=>100)
|
397
|
+
@ds.insert(:id=>4, :group_id=>2, :amount=>1000)
|
398
|
+
@ds.insert(:id=>5, :group_id=>2, :amount=>10000)
|
399
|
+
@ds.insert(:id=>6, :group_id=>2, :amount=>100000)
|
400
|
+
end
|
401
|
+
after do
|
402
|
+
@db.drop_table(:i1)
|
403
|
+
end
|
404
|
+
|
405
|
+
specify "should give correct results for aggregate window functions" do
|
406
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id){}.as(:sum)}.all.should ==
|
407
|
+
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
408
|
+
@ds.select(:id){sum(:over, :args=>amount){}.as(:sum)}.all.should ==
|
409
|
+
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
410
|
+
end
|
411
|
+
|
412
|
+
specify "should give correct results for ranking window functions with orders" do
|
413
|
+
@ds.select(:id){rank(:over, :partition=>group_id, :order=>id){}.as(:rank)}.all.should ==
|
414
|
+
[{:rank=>1, :id=>1}, {:rank=>2, :id=>2}, {:rank=>3, :id=>3}, {:rank=>1, :id=>4}, {:rank=>2, :id=>5}, {:rank=>3, :id=>6}]
|
415
|
+
@ds.select(:id){rank(:over, :order=>id){}.as(:rank)}.all.should ==
|
416
|
+
[{:rank=>1, :id=>1}, {:rank=>2, :id=>2}, {:rank=>3, :id=>3}, {:rank=>4, :id=>4}, {:rank=>5, :id=>5}, {:rank=>6, :id=>6}]
|
417
|
+
end
|
418
|
+
|
419
|
+
cspecify "should give correct results for aggregate window functions with orders", :mssql do
|
420
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id){}.as(:sum)}.all.should ==
|
421
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
422
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id){}.as(:sum)}.all.should ==
|
423
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
424
|
+
end
|
425
|
+
|
426
|
+
cspecify "should give correct results for aggregate window functions with frames", :mssql do
|
427
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:all){}.as(:sum)}.all.should ==
|
428
|
+
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
429
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:all){}.as(:sum)}.all.should ==
|
430
|
+
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
431
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:all){}.as(:sum)}.all.should ==
|
432
|
+
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
433
|
+
@ds.select(:id){sum(:over, :args=>amount, :frame=>:all){}.as(:sum)}.all.should ==
|
434
|
+
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
435
|
+
|
436
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:rows){}.as(:sum)}.all.should ==
|
437
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
438
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:rows){}.as(:sum)}.all.should ==
|
439
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
440
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:rows){}.as(:sum)}.all.should ==
|
441
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
442
|
+
@ds.select(:id){sum(:over, :args=>amount, :frame=>:rows){}.as(:sum)}.all.should ==
|
443
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe Sequel::SQL::Constants do
|
449
|
+
before do
|
450
|
+
@db = INTEGRATION_DB
|
451
|
+
@ds = @db[:constants]
|
452
|
+
@c = proc do |v|
|
453
|
+
case v
|
454
|
+
when Time
|
455
|
+
v
|
456
|
+
when DateTime, String
|
457
|
+
Time.parse(v.to_s)
|
458
|
+
else
|
459
|
+
v
|
460
|
+
end
|
461
|
+
end
|
462
|
+
@c2 = proc{|v| v.is_a?(Date) ? v : Date.parse(v) }
|
463
|
+
end
|
464
|
+
after do
|
465
|
+
@db.drop_table(:constants)
|
466
|
+
end
|
467
|
+
|
468
|
+
cspecify "should have working CURRENT_DATE", [:odbc, :mssql], [:jdbc, :sqlite] do
|
469
|
+
@db.create_table!(:constants){Date :d}
|
470
|
+
@ds.insert(:d=>Sequel::CURRENT_DATE)
|
471
|
+
Date.today.should == @c2[@ds.get(:d)]
|
472
|
+
end
|
473
|
+
|
474
|
+
cspecify "should have working CURRENT_TIME", [:do, :mysql], [:jdbc, :sqlite] do
|
475
|
+
@db.create_table!(:constants){Time :t, :only_time=>true}
|
476
|
+
@ds.insert(:t=>Sequel::CURRENT_TIME)
|
477
|
+
(Time.now - @c[@ds.get(:t)]).should be_close(0, 1)
|
478
|
+
end
|
479
|
+
|
480
|
+
cspecify "should have working CURRENT_TIMESTAMP", [:jdbc, :sqlite] do
|
481
|
+
@db.create_table!(:constants){DateTime :ts}
|
482
|
+
@ds.insert(:ts=>Sequel::CURRENT_TIMESTAMP)
|
483
|
+
(Time.now - @c[@ds.get(:ts)]).should be_close(0, 1)
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
describe "Sequel::Dataset#import and #multi_insert" do
|
488
|
+
before do
|
489
|
+
@db = INTEGRATION_DB
|
490
|
+
@db.create_table!(:imp){Integer :i}
|
491
|
+
@db.create_table!(:exp2){Integer :i}
|
492
|
+
@ids = @db[:imp].order(:i)
|
493
|
+
@eds = @db[:exp2]
|
494
|
+
end
|
495
|
+
after do
|
496
|
+
@db.drop_table(:imp, :exp2)
|
497
|
+
end
|
498
|
+
|
499
|
+
it "should import with multi_insert and an array of hashes" do
|
500
|
+
@ids.multi_insert([{:i=>10}, {:i=>20}])
|
501
|
+
@ids.all.should == [{:i=>10}, {:i=>20}]
|
502
|
+
end
|
503
|
+
|
504
|
+
it "should import with an array of arrays of values" do
|
505
|
+
@ids.import([:i], [[10], [20]])
|
506
|
+
@ids.all.should == [{:i=>10}, {:i=>20}]
|
507
|
+
end
|
508
|
+
|
509
|
+
it "should import with a dataset" do
|
510
|
+
@eds.import([:i], [[10], [20]])
|
511
|
+
@ids.import([:i], @eds)
|
512
|
+
@ids.all.should == [{:i=>10}, {:i=>20}]
|
513
|
+
end
|
514
|
+
|
515
|
+
it "should have import work with the :slice_size option" do
|
516
|
+
@ids.import([:i], [[10], [20], [30]], :slice_size=>1)
|
517
|
+
@ids.all.should == [{:i=>10}, {:i=>20}, {:i=>30}]
|
518
|
+
@ids.delete
|
519
|
+
@ids.import([:i], [[10], [20], [30]], :slice_size=>2)
|
520
|
+
@ids.all.should == [{:i=>10}, {:i=>20}, {:i=>30}]
|
521
|
+
@ids.delete
|
522
|
+
@ids.import([:i], [[10], [20], [30]], :slice_size=>3)
|
523
|
+
@ids.all.should == [{:i=>10}, {:i=>20}, {:i=>30}]
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
describe "Sequel::Dataset convenience methods" do
|
528
|
+
before do
|
529
|
+
@db = INTEGRATION_DB
|
530
|
+
@db.create_table!(:a){Integer :a; Integer :b}
|
531
|
+
@ds = @db[:a].order(:a)
|
532
|
+
end
|
533
|
+
after do
|
534
|
+
@db.drop_table(:a)
|
535
|
+
end
|
536
|
+
|
537
|
+
it "#[]= should update matching rows" do
|
538
|
+
@ds.insert(20, 10)
|
539
|
+
@ds[:a=>20] = {:b=>30}
|
540
|
+
@ds.all.should == [{:a=>20, :b=>30}]
|
541
|
+
end
|
542
|
+
|
543
|
+
it "#empty? should return whether the dataset returns no rows" do
|
544
|
+
@ds.empty?.should == true
|
545
|
+
@ds.insert(20, 10)
|
546
|
+
@ds.empty?.should == false
|
547
|
+
end
|
548
|
+
|
549
|
+
it "#group_and_count should return a grouping by count" do
|
550
|
+
@ds.group_and_count(:a).order(:count).all.should == []
|
551
|
+
@ds.insert(20, 10)
|
552
|
+
@ds.group_and_count(:a).order(:count).all.each{|h| h[:count] = h[:count].to_i}.should == [{:a=>20, :count=>1}]
|
553
|
+
@ds.insert(20, 30)
|
554
|
+
@ds.group_and_count(:a).order(:count).all.each{|h| h[:count] = h[:count].to_i}.should == [{:a=>20, :count=>2}]
|
555
|
+
@ds.insert(30, 30)
|
556
|
+
@ds.group_and_count(:a).order(:count).all.each{|h| h[:count] = h[:count].to_i}.should == [{:a=>30, :count=>1}, {:a=>20, :count=>2}]
|
557
|
+
end
|
558
|
+
|
559
|
+
it "#group_and_count should support column aliases" do
|
560
|
+
@ds.group_and_count(:a___c).order(:count).all.should == []
|
561
|
+
@ds.insert(20, 10)
|
562
|
+
@ds.group_and_count(:a___c).order(:count).all.each{|h| h[:count] = h[:count].to_i}.should == [{:c=>20, :count=>1}]
|
563
|
+
@ds.insert(20, 30)
|
564
|
+
@ds.group_and_count(:a___c).order(:count).all.each{|h| h[:count] = h[:count].to_i}.should == [{:c=>20, :count=>2}]
|
565
|
+
@ds.insert(30, 30)
|
566
|
+
@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}]
|
567
|
+
end
|
568
|
+
|
569
|
+
cspecify "#range should return the range between the maximum and minimum values", :sqlite do
|
570
|
+
@ds = @ds.unordered
|
571
|
+
@ds.insert(20, 10)
|
572
|
+
@ds.insert(30, 10)
|
573
|
+
@ds.range(:a).should == (20..30)
|
574
|
+
@ds.range(:b).should == (10..10)
|
575
|
+
end
|
576
|
+
|
577
|
+
it "#interval should return the different between the maximum and minimum values" do
|
578
|
+
@ds = @ds.unordered
|
579
|
+
@ds.insert(20, 10)
|
580
|
+
@ds.insert(30, 10)
|
581
|
+
@ds.interval(:a).to_i.should == 10
|
582
|
+
@ds.interval(:b).to_i.should == 0
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
describe "Sequel::Dataset main SQL methods" do
|
587
|
+
before do
|
588
|
+
@db = INTEGRATION_DB
|
589
|
+
@db.create_table!(:a){Integer :a; Integer :b}
|
590
|
+
@ds = @db[:a].order(:a)
|
591
|
+
end
|
592
|
+
after do
|
593
|
+
@db.drop_table(:a)
|
594
|
+
end
|
595
|
+
|
596
|
+
it "#exists should return a usable exists clause" do
|
597
|
+
@ds.filter(@db[:a___c].filter(:c__a=>:a__b).exists).all.should == []
|
598
|
+
@ds.insert(20, 30)
|
599
|
+
@ds.insert(10, 20)
|
600
|
+
@ds.filter(@db[:a___c].filter(:c__a=>:a__b).exists).all.should == [{:a=>10, :b=>20}]
|
601
|
+
end
|
602
|
+
|
603
|
+
it "#filter and #exclude should work with placeholder strings" do
|
604
|
+
@ds.insert(20, 30)
|
605
|
+
@ds.filter("a > ?", 15).all.should == [{:a=>20, :b=>30}]
|
606
|
+
@ds.exclude("b < ?", 15).all.should == [{:a=>20, :b=>30}]
|
607
|
+
@ds.filter("b < ?", 15).invert.all.should == [{:a=>20, :b=>30}]
|
608
|
+
end
|
609
|
+
|
610
|
+
it "#and and #or should work correctly" do
|
611
|
+
@ds.insert(20, 30)
|
612
|
+
@ds.filter(:a=>20).and(:b=>30).all.should == [{:a=>20, :b=>30}]
|
613
|
+
@ds.filter(:a=>20).and(:b=>15).all.should == []
|
614
|
+
@ds.filter(:a=>20).or(:b=>15).all.should == [{:a=>20, :b=>30}]
|
615
|
+
@ds.filter(:a=>10).or(:b=>15).all.should == []
|
616
|
+
end
|
617
|
+
|
618
|
+
it "#having should work correctly" do
|
619
|
+
@ds.unordered!
|
620
|
+
@ds.select{[b, max(a).as(c)]}.group(:b).having{max(a) > 30}.all.should == []
|
621
|
+
@ds.insert(20, 30)
|
622
|
+
@ds.select{[b, max(a).as(c)]}.group(:b).having{max(a) > 30}.all.should == []
|
623
|
+
@ds.insert(40, 20)
|
624
|
+
@ds.select{[b, max(a).as(c)]}.group(:b).having{max(a) > 30}.all.each{|h| h[:c] = h[:c].to_i}.should == [{:b=>20, :c=>40}]
|
625
|
+
end
|
626
|
+
|
627
|
+
cspecify "#having should work without a previous group", :sqlite do
|
628
|
+
@ds.unordered!
|
629
|
+
@ds.select{max(a).as(c)}.having{max(a) > 30}.all.should == []
|
630
|
+
@ds.insert(20, 30)
|
631
|
+
@ds.select{max(a).as(c)}.having{max(a) > 30}.all.should == []
|
632
|
+
@ds.insert(40, 20)
|
633
|
+
@ds.select{max(a).as(c)}.having{max(a) > 30}.all.each{|h| h[:c] = h[:c].to_i}.should == [{:c=>40}]
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
describe "Sequel::Dataset DSL support" do
|
638
|
+
before do
|
639
|
+
@db = INTEGRATION_DB
|
640
|
+
@db.create_table!(:a){Integer :a; Integer :b}
|
641
|
+
@ds = @db[:a].order(:a)
|
642
|
+
end
|
643
|
+
after do
|
644
|
+
@db.drop_table(:a)
|
645
|
+
end
|
646
|
+
|
647
|
+
it "should work with standard mathematical operators" do
|
648
|
+
@ds.insert(20, 10)
|
649
|
+
@ds.get{a + b}.to_i.should == 30
|
650
|
+
@ds.get{a - b}.to_i.should == 10
|
651
|
+
@ds.get{a * b}.to_i.should == 200
|
652
|
+
@ds.get{a / b}.to_i.should == 2
|
653
|
+
end
|
654
|
+
|
655
|
+
cspecify "should work with standard bitwise mathematical operators", :mssql, :h2 do
|
656
|
+
@ds.insert(24, 2)
|
657
|
+
@ds.get{a.sql_number << b}.to_i.should == 96
|
658
|
+
@ds.get{a.sql_number >> b}.to_i.should == 6
|
659
|
+
@ds.delete
|
660
|
+
@ds.insert(3, 5)
|
661
|
+
@ds.get{a.sql_number | b}.to_i.should == 7
|
662
|
+
@ds.get{a.sql_number & b}.to_i.should == 1
|
663
|
+
end
|
664
|
+
|
665
|
+
cspecify "should work with the bitwise compliment operator", :mysql, :h2 do
|
666
|
+
@ds.insert(3, 5)
|
667
|
+
@ds.get{~a.sql_number}.to_i.should == -4
|
668
|
+
end
|
669
|
+
|
670
|
+
cspecify "should work with inequality operators", :mssql do
|
671
|
+
@ds.insert(20, 20)
|
672
|
+
['0', 0, false].should include(@ds.get{a > b})
|
673
|
+
['0', 0, false].should include(@ds.get{a < b})
|
674
|
+
['1', 1, true].should include(@ds.get{a <= b})
|
675
|
+
['1', 1, true].should include(@ds.get{a >= b})
|
676
|
+
end
|
677
|
+
|
678
|
+
cspecify "should work with casting and string concatentation", :mssql do
|
679
|
+
@ds.insert(20, 20)
|
680
|
+
@ds.get{a.cast_string + b}.should == '2020'
|
681
|
+
end
|
682
|
+
|
683
|
+
it "should work with ordering" do
|
684
|
+
@ds.insert(10, 20)
|
685
|
+
@ds.insert(20, 10)
|
686
|
+
@ds.order(:a, :b).all.should == [{:a=>10, :b=>20}, {:a=>20, :b=>10}]
|
687
|
+
@ds.order(:a.asc, :b.asc).all.should == [{:a=>10, :b=>20}, {:a=>20, :b=>10}]
|
688
|
+
@ds.order(:a.desc, :b.desc).all.should == [{:a=>20, :b=>10}, {:a=>10, :b=>20}]
|
689
|
+
end
|
690
|
+
|
691
|
+
it "should work with qualifying" do
|
692
|
+
@ds.insert(10, 20)
|
693
|
+
@ds.get(:a__b).should == 20
|
694
|
+
@ds.get{a__b}.should == 20
|
695
|
+
@ds.get(:b.qualify(:a)).should == 20
|
696
|
+
end
|
697
|
+
|
698
|
+
it "should work with aliasing" do
|
699
|
+
@ds.insert(10, 20)
|
700
|
+
@ds.get(:a__b___c).should == 20
|
701
|
+
@ds.get{a__b.as(c)}.should == 20
|
702
|
+
@ds.get(:b.qualify(:a).as(:c)).should == 20
|
703
|
+
@ds.get(:b.as(:c)).should == 20
|
704
|
+
end
|
705
|
+
|
706
|
+
it "should work with selecting all columns of a table" do
|
707
|
+
@ds.insert(20, 10)
|
708
|
+
@ds.select(:a.*).all.should == [{:a=>20, :b=>10}]
|
709
|
+
end
|
710
|
+
|
711
|
+
it "should work with ranges as hash values" do
|
712
|
+
@ds.insert(20, 10)
|
713
|
+
@ds.filter(:a=>(10..30)).all.should == [{:a=>20, :b=>10}]
|
714
|
+
@ds.filter(:a=>(25..30)).all.should == []
|
715
|
+
@ds.filter(:a=>(10..15)).all.should == []
|
716
|
+
@ds.exclude(:a=>(10..30)).all.should == []
|
717
|
+
@ds.exclude(:a=>(25..30)).all.should == [{:a=>20, :b=>10}]
|
718
|
+
@ds.exclude(:a=>(10..15)).all.should == [{:a=>20, :b=>10}]
|
719
|
+
end
|
720
|
+
|
721
|
+
it "should work with nil as hash value" do
|
722
|
+
@ds.insert(20, nil)
|
723
|
+
@ds.filter(:a=>nil).all.should == []
|
724
|
+
@ds.filter(:b=>nil).all.should == [{:a=>20, :b=>nil}]
|
725
|
+
@ds.exclude(:b=>nil).all.should == []
|
726
|
+
@ds.exclude(:a=>nil).all.should == [{:a=>20, :b=>nil}]
|
727
|
+
end
|
728
|
+
|
729
|
+
it "should work with arrays as hash values" do
|
730
|
+
@ds.insert(20, 10)
|
731
|
+
@ds.filter(:a=>[10]).all.should == []
|
732
|
+
@ds.filter(:a=>[20, 10]).all.should == [{:a=>20, :b=>10}]
|
733
|
+
@ds.exclude(:a=>[10]).all.should == [{:a=>20, :b=>10}]
|
734
|
+
@ds.exclude(:a=>[20, 10]).all.should == []
|
735
|
+
end
|
736
|
+
|
737
|
+
it "should work with ranges as hash values" do
|
738
|
+
@ds.insert(20, 10)
|
739
|
+
@ds.filter(:a=>(10..30)).all.should == [{:a=>20, :b=>10}]
|
740
|
+
@ds.filter(:a=>(25..30)).all.should == []
|
741
|
+
@ds.filter(:a=>(10..15)).all.should == []
|
742
|
+
@ds.exclude(:a=>(10..30)).all.should == []
|
743
|
+
@ds.exclude(:a=>(25..30)).all.should == [{:a=>20, :b=>10}]
|
744
|
+
@ds.exclude(:a=>(10..15)).all.should == [{:a=>20, :b=>10}]
|
745
|
+
end
|
746
|
+
|
747
|
+
it "should work with CASE statements" do
|
748
|
+
@ds.insert(20, 10)
|
749
|
+
@ds.filter({{:a=>20}=>20}.case(0) > 0).all.should == [{:a=>20, :b=>10}]
|
750
|
+
@ds.filter({{:a=>15}=>20}.case(0) > 0).all.should == []
|
751
|
+
@ds.filter({20=>20}.case(0, :a) > 0).all.should == [{:a=>20, :b=>10}]
|
752
|
+
@ds.filter({15=>20}.case(0, :a) > 0).all.should == []
|
753
|
+
end
|
754
|
+
|
755
|
+
it "should work with multiple value arrays" do
|
756
|
+
@ds.insert(20, 10)
|
757
|
+
@ds.quote_identifiers = false
|
758
|
+
@ds.filter([:a, :b]=>[[20, 10]].sql_array).all.should == [{:a=>20, :b=>10}]
|
759
|
+
@ds.filter([:a, :b]=>[[10, 20]].sql_array).all.should == []
|
760
|
+
@ds.filter([:a, :b]=>[[20, 10], [1, 2]].sql_array).all.should == [{:a=>20, :b=>10}]
|
761
|
+
@ds.filter([:a, :b]=>[[10, 10], [20, 20]].sql_array).all.should == []
|
762
|
+
|
763
|
+
@ds.exclude([:a, :b]=>[[20, 10]].sql_array).all.should == []
|
764
|
+
@ds.exclude([:a, :b]=>[[10, 20]].sql_array).all.should == [{:a=>20, :b=>10}]
|
765
|
+
@ds.exclude([:a, :b]=>[[20, 10], [1, 2]].sql_array).all.should == []
|
766
|
+
@ds.exclude([:a, :b]=>[[10, 10], [20, 20]].sql_array).all.should == [{:a=>20, :b=>10}]
|
767
|
+
end
|
768
|
+
|
769
|
+
it "should work with IN/NOT in with datasets" do
|
770
|
+
@ds.insert(20, 10)
|
771
|
+
ds = @ds.unordered
|
772
|
+
@ds.quote_identifiers = false
|
773
|
+
|
774
|
+
@ds.filter(:a=>ds.select(:a)).all.should == [{:a=>20, :b=>10}]
|
775
|
+
@ds.filter(:a=>ds.select(:a).where(:a=>15)).all.should == []
|
776
|
+
@ds.exclude(:a=>ds.select(:a)).all.should == []
|
777
|
+
@ds.exclude(:a=>ds.select(:a).where(:a=>15)).all.should == [{:a=>20, :b=>10}]
|
778
|
+
|
779
|
+
@ds.filter([:a, :b]=>ds.select(:a, :b)).all.should == [{:a=>20, :b=>10}]
|
780
|
+
@ds.filter([:a, :b]=>ds.select(:b, :a)).all.should == []
|
781
|
+
@ds.exclude([:a, :b]=>ds.select(:a, :b)).all.should == []
|
782
|
+
@ds.exclude([:a, :b]=>ds.select(:b, :a)).all.should == [{:a=>20, :b=>10}]
|
783
|
+
|
784
|
+
@ds.filter([:a, :b]=>ds.select(:a, :b).where(:a=>15)).all.should == []
|
785
|
+
@ds.exclude([:a, :b]=>ds.select(:a, :b).where(:a=>15)).all.should == [{:a=>20, :b=>10}]
|
786
|
+
end
|
787
|
+
|
788
|
+
specify "should work empty arrays" do
|
789
|
+
@ds.insert(20, 10)
|
790
|
+
@ds.filter(:a=>[]).all.should == []
|
791
|
+
@ds.exclude(:a=>[]).all.should == [{:a=>20, :b=>10}]
|
792
|
+
@ds.filter([:a, :b]=>[]).all.should == []
|
793
|
+
@ds.exclude([:a, :b]=>[]).all.should == [{:a=>20, :b=>10}]
|
794
|
+
end
|
795
|
+
|
796
|
+
specify "should work empty arrays with nulls" do
|
797
|
+
@ds.insert(nil, nil)
|
798
|
+
@ds.filter(:a=>[]).all.should == []
|
799
|
+
@ds.exclude(:a=>[]).all.should == [{:a=>nil, :b=>nil}]
|
800
|
+
@ds.filter([:a, :b]=>[]).all.should == []
|
801
|
+
@ds.exclude([:a, :b]=>[]).all.should == [{:a=>nil, :b=>nil}]
|
802
|
+
end
|
803
|
+
|
804
|
+
it "should work multiple conditions" do
|
805
|
+
@ds.insert(20, 10)
|
806
|
+
@ds.filter(:a=>20, :b=>10).all.should == [{:a=>20, :b=>10}]
|
807
|
+
@ds.filter([[:a, 20], [:b, 10]]).all.should == [{:a=>20, :b=>10}]
|
808
|
+
@ds.filter({:a=>20} & {:b=>10}).all.should == [{:a=>20, :b=>10}]
|
809
|
+
@ds.filter({:a=>20} | {:b=>5}).all.should == [{:a=>20, :b=>10}]
|
810
|
+
@ds.filter(~{:a=>10}).all.should == [{:a=>20, :b=>10}]
|
811
|
+
end
|
812
|
+
end
|
813
|
+
|
814
|
+
describe "SQL Extract Function" do
|
815
|
+
before do
|
816
|
+
@db = INTEGRATION_DB
|
817
|
+
@db.create_table!(:a){DateTime :a}
|
818
|
+
@ds = @db[:a].order(:a)
|
819
|
+
end
|
820
|
+
after do
|
821
|
+
@db.drop_table(:a)
|
822
|
+
end
|
823
|
+
|
824
|
+
cspecify "should return the part of the datetime asked for", :sqlite, :mssql do
|
825
|
+
t = Time.now
|
826
|
+
@ds.insert(t)
|
827
|
+
@ds.get{a.extract(:year)}.should == t.year
|
828
|
+
@ds.get{a.extract(:month)}.should == t.month
|
829
|
+
@ds.get{a.extract(:day)}.should == t.day
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
833
|
+
describe "Dataset string methods" do
|
834
|
+
before do
|
835
|
+
@db = INTEGRATION_DB
|
836
|
+
@db.create_table!(:a){String :a; String :b}
|
837
|
+
@ds = @db[:a].order(:a)
|
838
|
+
end
|
839
|
+
after do
|
840
|
+
@db.drop_table(:a)
|
841
|
+
end
|
842
|
+
|
843
|
+
it "#grep should return matching rows" do
|
844
|
+
@ds.insert('foo', 'bar')
|
845
|
+
@ds.grep(:a, 'foo').all.should == [{:a=>'foo', :b=>'bar'}]
|
846
|
+
@ds.grep(:b, 'foo').all.should == []
|
847
|
+
@ds.grep(:b, 'bar').all.should == [{:a=>'foo', :b=>'bar'}]
|
848
|
+
@ds.grep(:a, 'bar').all.should == []
|
849
|
+
@ds.grep([:a, :b], %w'foo bar').all.should == [{:a=>'foo', :b=>'bar'}]
|
850
|
+
@ds.grep([:a, :b], %w'boo far').all.should == []
|
851
|
+
end
|
852
|
+
|
853
|
+
it "#like should return matching rows" do
|
854
|
+
@ds.insert('foo', 'bar')
|
855
|
+
@ds.filter(:a.like('foo')).all.should == [{:a=>'foo', :b=>'bar'}]
|
856
|
+
@ds.filter(:a.like('bar')).all.should == []
|
857
|
+
@ds.filter(:a.like('foo', 'bar')).all.should == [{:a=>'foo', :b=>'bar'}]
|
858
|
+
end
|
859
|
+
|
860
|
+
it "#ilike should return matching rows, in a case insensitive manner" do
|
861
|
+
@ds.insert('foo', 'bar')
|
862
|
+
@ds.filter(:a.ilike('Foo')).all.should == [{:a=>'foo', :b=>'bar'}]
|
863
|
+
@ds.filter(:a.ilike('baR')).all.should == []
|
864
|
+
@ds.filter(:a.ilike('FOO', 'BAR')).all.should == [{:a=>'foo', :b=>'bar'}]
|
865
|
+
end
|
866
|
+
|
867
|
+
it "should work with strings created with sql_string_join" do
|
868
|
+
@ds.insert('foo', 'bar')
|
869
|
+
@ds.get([:a, :b].sql_string_join).should == 'foobar'
|
870
|
+
@ds.get([:a, :b].sql_string_join(' ')).should == 'foo bar'
|
871
|
+
end
|
872
|
+
end
|
873
|
+
|
874
|
+
describe "Dataset identifier methods" do
|
875
|
+
before do
|
876
|
+
class ::String
|
877
|
+
def uprev
|
878
|
+
upcase.reverse
|
879
|
+
end
|
880
|
+
end
|
881
|
+
@db = INTEGRATION_DB
|
882
|
+
@db.create_table!(:a){Integer :ab}
|
883
|
+
@ds = @db[:a].order(:ab)
|
884
|
+
@ds.insert(1)
|
885
|
+
end
|
886
|
+
after do
|
887
|
+
@db.drop_table(:a)
|
888
|
+
end
|
889
|
+
|
890
|
+
it "#identifier_output_method should change how identifiers are output" do
|
891
|
+
@ds.identifier_output_method = :upcase
|
892
|
+
@ds.first.should == {:AB=>1}
|
893
|
+
@ds.identifier_output_method = :uprev
|
894
|
+
@ds.first.should == {:BA=>1}
|
895
|
+
end
|
896
|
+
|
897
|
+
it "should work when not quoting identifiers" do
|
898
|
+
@ds.quote_identifiers = false
|
899
|
+
@ds.first.should == {:ab=>1}
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
describe "Dataset defaults and overrides" do
|
904
|
+
before do
|
905
|
+
@db = INTEGRATION_DB
|
906
|
+
@db.create_table!(:a){Integer :a}
|
907
|
+
@ds = @db[:a].order(:a)
|
908
|
+
end
|
909
|
+
after do
|
910
|
+
@db.drop_table(:a)
|
911
|
+
end
|
912
|
+
|
913
|
+
it "#set_defaults should set defaults that can be overridden" do
|
914
|
+
@ds = @ds.set_defaults(:a=>10)
|
915
|
+
@ds.insert
|
916
|
+
@ds.insert(:a=>20)
|
917
|
+
@ds.all.should == [{:a=>10}, {:a=>20}]
|
918
|
+
end
|
919
|
+
|
920
|
+
it "#set_overrides should set defaults that cannot be overridden" do
|
921
|
+
@ds = @ds.set_overrides(:a=>10)
|
922
|
+
@ds.insert
|
923
|
+
@ds.insert(:a=>20)
|
924
|
+
@ds.all.should == [{:a=>10}, {:a=>10}]
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
928
|
+
if INTEGRATION_DB.dataset.supports_modifying_joins?
|
929
|
+
describe "Modifying joined datasets" do
|
930
|
+
before do
|
931
|
+
@db = INTEGRATION_DB
|
932
|
+
@db.create_table!(:a){Integer :a; Integer :d}
|
933
|
+
@db.create_table!(:b){Integer :b; Integer :e}
|
934
|
+
@db.create_table!(:c){Integer :c; Integer :f}
|
935
|
+
@ds = @db.from(:a, :b).join(:c, :c=>:e.identifier).where(:d=>:b, :f=>6)
|
936
|
+
@db[:a].insert(1, 2)
|
937
|
+
@db[:a].insert(3, 4)
|
938
|
+
@db[:b].insert(2, 5)
|
939
|
+
@db[:c].insert(5, 6)
|
940
|
+
@db[:b].insert(4, 7)
|
941
|
+
@db[:c].insert(7, 8)
|
942
|
+
end
|
943
|
+
after do
|
944
|
+
@db.drop_table(:a, :b, :c)
|
945
|
+
end
|
946
|
+
|
947
|
+
it "#update should allow updating joined datasets" do
|
948
|
+
@ds.update(:a=>10)
|
949
|
+
@ds.all.should == [{:c=>5, :b=>2, :a=>10, :d=>2, :e=>5, :f=>6}]
|
950
|
+
@db[:a].order(:a).all.should == [{:a=>3, :d=>4}, {:a=>10, :d=>2}]
|
951
|
+
@db[:b].order(:b).all.should == [{:b=>2, :e=>5}, {:b=>4, :e=>7}]
|
952
|
+
@db[:c].order(:c).all.should == [{:c=>5, :f=>6}, {:c=>7, :f=>8}]
|
953
|
+
end
|
954
|
+
|
955
|
+
it "#delete should allow deleting from joined datasets" do
|
956
|
+
@ds.delete
|
957
|
+
@ds.all.should == []
|
958
|
+
@db[:a].order(:a).all.should == [{:a=>3, :d=>4}]
|
959
|
+
@db[:b].order(:b).all.should == [{:b=>2, :e=>5}, {:b=>4, :e=>7}]
|
960
|
+
@db[:c].order(:c).all.should == [{:c=>5, :f=>6}, {:c=>7, :f=>8}]
|
961
|
+
end
|
962
|
+
end
|
963
|
+
end
|