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,213 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe "Prepared Statements and Bound Arguments" do
|
4
|
+
before do
|
5
|
+
INTEGRATION_DB.create_table!(:items) do
|
6
|
+
primary_key :id
|
7
|
+
integer :number
|
8
|
+
end
|
9
|
+
@c = Class.new(Sequel::Model(:items))
|
10
|
+
@ds = INTEGRATION_DB[:items]
|
11
|
+
@ds.insert(:number=>10)
|
12
|
+
@ds.meta_def(:ba) do |sym|
|
13
|
+
prepared_arg_placeholder == '$' ? :"#{sym}__int" : sym
|
14
|
+
end
|
15
|
+
clear_sqls
|
16
|
+
end
|
17
|
+
after do
|
18
|
+
INTEGRATION_DB.drop_table(:items)
|
19
|
+
end
|
20
|
+
|
21
|
+
specify "should support bound variables with select, all, and first" do
|
22
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
|
23
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:all, :n=>10).should == [{:id=>1, :number=>10}]
|
24
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:first, :n=>10).should == {:id=>1, :number=>10}
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "should support blocks for select and all" do
|
28
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:select, :n=>10){|r| r[:number] *= 2}.should == [{:id=>1, :number=>20}]
|
29
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:all, :n=>10){|r| r[:number] *= 2}.should == [{:id=>1, :number=>20}]
|
30
|
+
end
|
31
|
+
|
32
|
+
specify "should support binding variables before the call with #bind" do
|
33
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>10).call(:select).should == [{:id=>1, :number=>10}]
|
34
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>10).call(:all).should == [{:id=>1, :number=>10}]
|
35
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>10).call(:first).should == {:id=>1, :number=>10}
|
36
|
+
|
37
|
+
@ds.bind(:n=>10).filter(:number=>@ds.ba(:$n)).call(:select).should == [{:id=>1, :number=>10}]
|
38
|
+
@ds.bind(:n=>10).filter(:number=>@ds.ba(:$n)).call(:all).should == [{:id=>1, :number=>10}]
|
39
|
+
@ds.bind(:n=>10).filter(:number=>@ds.ba(:$n)).call(:first).should == {:id=>1, :number=>10}
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "should allow overriding variables specified with #bind" do
|
43
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
|
44
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).call(:all, :n=>10).should == [{:id=>1, :number=>10}]
|
45
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).call(:first, :n=>10).should == {:id=>1, :number=>10}
|
46
|
+
|
47
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).bind(:n=>10).call(:select).should == [{:id=>1, :number=>10}]
|
48
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).bind(:n=>10).call(:all).should == [{:id=>1, :number=>10}]
|
49
|
+
@ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).bind(:n=>10).call(:first).should == {:id=>1, :number=>10}
|
50
|
+
end
|
51
|
+
|
52
|
+
specify "should support placeholder literal strings with call" do
|
53
|
+
@ds.filter("number = ?", @ds.ba(:$n)).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
|
54
|
+
end
|
55
|
+
|
56
|
+
specify "should support named placeholder literal strings and handle multiple named placeholders correctly with call" do
|
57
|
+
@ds.filter("number = :n", :n=>@ds.ba(:$n)).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
|
58
|
+
@ds.insert(:number=>20)
|
59
|
+
@ds.insert(:number=>30)
|
60
|
+
@ds.filter("number > :n1 AND number < :n2 AND number = :n3", :n3=>@ds.ba(:$n3), :n2=>@ds.ba(:$n2), :n1=>@ds.ba(:$n1)).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :number=>20}]
|
61
|
+
end
|
62
|
+
|
63
|
+
specify "should support datasets with static sql and placeholders with call" do
|
64
|
+
INTEGRATION_DB["SELECT * FROM items WHERE number = ?", @ds.ba(:$n)].call(:select, :n=>10).should == [{:id=>1, :number=>10}]
|
65
|
+
end
|
66
|
+
|
67
|
+
specify "should support subselects with call" do
|
68
|
+
@ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
|
69
|
+
end
|
70
|
+
|
71
|
+
specify "should support subselects with literal strings with call" do
|
72
|
+
@ds.filter(:id=>:$i, :number=>@ds.select(:number).filter("number = ?", @ds.ba(:$n))).call(:select, :n=>10, :i=>1).should == [{:id=>1, :number=>10}]
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "should support subselects with static sql and placeholders with call" do
|
76
|
+
@ds.filter(:id=>:$i, :number=>INTEGRATION_DB["SELECT number FROM items WHERE number = ?", @ds.ba(:$n)]).call(:select, :n=>10, :i=>1).should == [{:id=>1, :number=>10}]
|
77
|
+
end
|
78
|
+
|
79
|
+
specify "should support subselects of subselects with call" do
|
80
|
+
@ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n)))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
|
81
|
+
end
|
82
|
+
|
83
|
+
specify "should support using a bound variable for a limit and offset" do
|
84
|
+
@ds.insert(:number=>20)
|
85
|
+
ds = @ds.limit(@ds.ba(:$n), @ds.ba(:$n2)).order(:id)
|
86
|
+
ds.call(:select, :n=>1, :n2=>0).should == [{:id=>1, :number=>10}]
|
87
|
+
ds.call(:select, :n=>1, :n2=>1).should == [{:id=>2, :number=>20}]
|
88
|
+
ds.call(:select, :n=>1, :n2=>2).should == []
|
89
|
+
ds.call(:select, :n=>2, :n2=>0).should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
90
|
+
ds.call(:select, :n=>2, :n2=>1).should == [{:id=>2, :number=>20}]
|
91
|
+
end
|
92
|
+
|
93
|
+
specify "should support bound variables with insert" do
|
94
|
+
@ds.call(:insert, {:n=>20}, :number=>@ds.ba(:$n))
|
95
|
+
@ds.count.should == 2
|
96
|
+
@ds.order(:id).map(:number).should == [10, 20]
|
97
|
+
end
|
98
|
+
|
99
|
+
specify "should have insert return primary key value when using bound arguments" do
|
100
|
+
@ds.call(:insert, {:n=>20}, :number=>@ds.ba(:$n)).should == 2
|
101
|
+
@ds.filter(:id=>2).first[:number].should == 20
|
102
|
+
end
|
103
|
+
|
104
|
+
specify "should support bound variables with delete" do
|
105
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:delete, :n=>10).should == 1
|
106
|
+
@ds.count.should == 0
|
107
|
+
end
|
108
|
+
|
109
|
+
specify "should support bound variables with update" do
|
110
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:update, {:n=>10, :nn=>20}, :number=>:number+@ds.ba(:$nn)).should == 1
|
111
|
+
@ds.all.should == [{:id=>1, :number=>30}]
|
112
|
+
end
|
113
|
+
|
114
|
+
specify "should support prepared statements with select, first, and all" do
|
115
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:select, :select_n)
|
116
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
|
117
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:all, :select_n)
|
118
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
|
119
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:first, :select_n)
|
120
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == {:id=>1, :number=>10}
|
121
|
+
if INTEGRATION_DB.class.adapter_scheme == :jdbc and INTEGRATION_DB.database_type == :sqlite
|
122
|
+
# Work around for open prepared statements on a table not allowing the
|
123
|
+
# dropping of a table when using SQLite over JDBC
|
124
|
+
INTEGRATION_DB.synchronize{|c| c.prepared_statements[:select_n][1].close}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
specify "should support placeholder literal strings with prepare" do
|
129
|
+
@ds.filter("number = ?", @ds.ba(:$n)).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
|
130
|
+
end
|
131
|
+
|
132
|
+
specify "should support named placeholder literal strings and handle multiple named placeholders correctly with prepare" do
|
133
|
+
@ds.filter("number = :n", :n=>@ds.ba(:$n)).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
|
134
|
+
@ds.insert(:number=>20)
|
135
|
+
@ds.insert(:number=>30)
|
136
|
+
@ds.filter("number > :n1 AND number < :n2 AND number = :n3", :n3=>@ds.ba(:$n3), :n2=>@ds.ba(:$n2), :n1=>@ds.ba(:$n1)).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :number=>20}]
|
137
|
+
end
|
138
|
+
|
139
|
+
specify "should support datasets with static sql and placeholders with prepare" do
|
140
|
+
INTEGRATION_DB["SELECT * FROM items WHERE number = ?", @ds.ba(:$n)].prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
|
141
|
+
end
|
142
|
+
|
143
|
+
specify "should support subselects with prepare" do
|
144
|
+
@ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
|
145
|
+
end
|
146
|
+
|
147
|
+
specify "should support subselects with literal strings with prepare" do
|
148
|
+
@ds.filter(:id=>:$i, :number=>@ds.select(:number).filter("number = ?", @ds.ba(:$n))).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :number=>10}]
|
149
|
+
end
|
150
|
+
|
151
|
+
specify "should support subselects with static sql and placeholders with prepare" do
|
152
|
+
@ds.filter(:id=>:$i, :number=>INTEGRATION_DB["SELECT number FROM items WHERE number = ?", @ds.ba(:$n)]).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :number=>10}]
|
153
|
+
end
|
154
|
+
|
155
|
+
specify "should support subselects of subselects with prepare" do
|
156
|
+
@ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n)))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
|
157
|
+
end
|
158
|
+
|
159
|
+
specify "should support using a prepared_statement for a limit and offset" do
|
160
|
+
@ds.insert(:number=>20)
|
161
|
+
ps = @ds.limit(@ds.ba(:$n), @ds.ba(:$n2)).order(:id).prepare(:select, :seq_select)
|
162
|
+
ps.call(:n=>1, :n2=>0).should == [{:id=>1, :number=>10}]
|
163
|
+
ps.call(:n=>1, :n2=>1).should == [{:id=>2, :number=>20}]
|
164
|
+
ps.call(:n=>1, :n2=>2).should == []
|
165
|
+
ps.call(:n=>2, :n2=>0).should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
166
|
+
ps.call(:n=>2, :n2=>1).should == [{:id=>2, :number=>20}]
|
167
|
+
end
|
168
|
+
|
169
|
+
specify "should support prepared statements with insert" do
|
170
|
+
@ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
|
171
|
+
INTEGRATION_DB.call(:insert_n, :n=>20)
|
172
|
+
@ds.count.should == 2
|
173
|
+
@ds.order(:id).map(:number).should == [10, 20]
|
174
|
+
end
|
175
|
+
|
176
|
+
specify "should have insert return primary key value when using prepared statements" do
|
177
|
+
@ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
|
178
|
+
INTEGRATION_DB.call(:insert_n, :n=>20).should == 2
|
179
|
+
@ds.filter(:id=>2).first[:number].should == 20
|
180
|
+
end
|
181
|
+
|
182
|
+
specify "should support prepared statements with delete" do
|
183
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:delete, :delete_n)
|
184
|
+
INTEGRATION_DB.call(:delete_n, :n=>10).should == 1
|
185
|
+
@ds.count.should == 0
|
186
|
+
end
|
187
|
+
|
188
|
+
specify "should support prepared statements with update" do
|
189
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:update, :update_n, :number=>:number+@ds.ba(:$nn))
|
190
|
+
INTEGRATION_DB.call(:update_n, :n=>10, :nn=>20).should == 1
|
191
|
+
@ds.all.should == [{:id=>1, :number=>30}]
|
192
|
+
end
|
193
|
+
|
194
|
+
specify "model datasets should return model instances when using select, all, and first with bound variables" do
|
195
|
+
@c.filter(:number=>@ds.ba(:$n)).call(:select, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
196
|
+
@c.filter(:number=>@ds.ba(:$n)).call(:all, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
197
|
+
@c.filter(:number=>@ds.ba(:$n)).call(:first, :n=>10).should == @c.load(:id=>1, :number=>10)
|
198
|
+
end
|
199
|
+
|
200
|
+
specify "model datasets should return model instances when using select, all, and first with prepared statements" do
|
201
|
+
@c.filter(:number=>@ds.ba(:$n)).prepare(:select, :select_n)
|
202
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
203
|
+
@c.filter(:number=>@ds.ba(:$n)).prepare(:all, :select_n)
|
204
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
205
|
+
@c.filter(:number=>@ds.ba(:$n)).prepare(:first, :select_n)
|
206
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == @c.load(:id=>1, :number=>10)
|
207
|
+
if INTEGRATION_DB.class.adapter_scheme == :jdbc and INTEGRATION_DB.database_type == :sqlite
|
208
|
+
# Work around for open prepared statements on a table not allowing the
|
209
|
+
# dropping of a table when using SQLite over JDBC
|
210
|
+
INTEGRATION_DB.synchronize{|c| c.prepared_statements[:select_n][1].close}
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,361 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
|
+
|
3
|
+
if INTEGRATION_DB.respond_to?(:schema_parse_table, true)
|
4
|
+
describe "Database schema parser" do
|
5
|
+
before do
|
6
|
+
@iom = INTEGRATION_DB.identifier_output_method
|
7
|
+
@iim = INTEGRATION_DB.identifier_input_method
|
8
|
+
@defsch = INTEGRATION_DB.default_schema
|
9
|
+
clear_sqls
|
10
|
+
end
|
11
|
+
after do
|
12
|
+
INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
|
13
|
+
INTEGRATION_DB.identifier_output_method = @iom
|
14
|
+
INTEGRATION_DB.identifier_input_method = @iim
|
15
|
+
INTEGRATION_DB.default_schema = @defsch
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should handle a database with a identifier_output_method" do
|
19
|
+
INTEGRATION_DB.identifier_output_method = :reverse
|
20
|
+
INTEGRATION_DB.identifier_input_method = :reverse
|
21
|
+
INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
|
22
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
23
|
+
INTEGRATION_DB.schema(:items, :reload=>true).should be_a_kind_of(Array)
|
24
|
+
INTEGRATION_DB.schema(:items, :reload=>true).first.first.should == :number
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "should not issue an sql query if the schema has been loaded unless :reload is true" do
|
28
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
29
|
+
INTEGRATION_DB.schema(:items, :reload=>true)
|
30
|
+
clear_sqls
|
31
|
+
INTEGRATION_DB.schema(:items)
|
32
|
+
clear_sqls
|
33
|
+
INTEGRATION_DB.schema(:items, :reload=>true)
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "should raise an error when the table doesn't exist" do
|
37
|
+
proc{INTEGRATION_DB.schema(:no_table)}.should raise_error(Sequel::Error)
|
38
|
+
end
|
39
|
+
|
40
|
+
specify "should return the schema correctly" do
|
41
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
42
|
+
schema = INTEGRATION_DB.schema(:items, :reload=>true)
|
43
|
+
schema.should be_a_kind_of(Array)
|
44
|
+
schema.length.should == 1
|
45
|
+
col = schema.first
|
46
|
+
col.should be_a_kind_of(Array)
|
47
|
+
col.length.should == 2
|
48
|
+
col.first.should == :number
|
49
|
+
col_info = col.last
|
50
|
+
col_info.should be_a_kind_of(Hash)
|
51
|
+
col_info[:type].should == :integer
|
52
|
+
clear_sqls
|
53
|
+
INTEGRATION_DB.schema(:items)
|
54
|
+
end
|
55
|
+
|
56
|
+
cspecify "should parse primary keys from the schema properly", [proc{|db| db.class.adapter_scheme != :jdbc}, :mssql] do
|
57
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
58
|
+
INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == []
|
59
|
+
INTEGRATION_DB.create_table!(:items){primary_key :number}
|
60
|
+
INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == [:number]
|
61
|
+
INTEGRATION_DB.create_table!(:items){Integer :number1; Integer :number2; primary_key [:number1, :number2]}
|
62
|
+
INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == [:number1, :number2]
|
63
|
+
end
|
64
|
+
|
65
|
+
specify "should parse NULL/NOT NULL from the schema properly" do
|
66
|
+
INTEGRATION_DB.create_table!(:items){Integer :number, :null=>true}
|
67
|
+
INTEGRATION_DB.schema(:items).first.last[:allow_null].should == true
|
68
|
+
INTEGRATION_DB.create_table!(:items){Integer :number, :null=>false}
|
69
|
+
INTEGRATION_DB.schema(:items).first.last[:allow_null].should == false
|
70
|
+
end
|
71
|
+
|
72
|
+
specify "should parse defaults from the schema properly" do
|
73
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
74
|
+
INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == nil
|
75
|
+
INTEGRATION_DB.create_table!(:items){Integer :number, :default=>0}
|
76
|
+
INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 0
|
77
|
+
INTEGRATION_DB.create_table!(:items){String :a, :default=>"blah"}
|
78
|
+
INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 'blah'
|
79
|
+
end
|
80
|
+
|
81
|
+
cspecify "should parse types from the schema properly", [:jdbc, :mysql] do
|
82
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
83
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
|
84
|
+
INTEGRATION_DB.create_table!(:items){Fixnum :number}
|
85
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
|
86
|
+
INTEGRATION_DB.create_table!(:items){Bignum :number}
|
87
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
|
88
|
+
INTEGRATION_DB.create_table!(:items){Float :number}
|
89
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :float
|
90
|
+
INTEGRATION_DB.create_table!(:items){BigDecimal :number}
|
91
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :decimal
|
92
|
+
INTEGRATION_DB.create_table!(:items){Numeric :number}
|
93
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :decimal
|
94
|
+
INTEGRATION_DB.create_table!(:items){String :number}
|
95
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :string
|
96
|
+
INTEGRATION_DB.create_table!(:items){Date :number}
|
97
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :date
|
98
|
+
INTEGRATION_DB.create_table!(:items){Time :number}
|
99
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :datetime
|
100
|
+
INTEGRATION_DB.create_table!(:items){DateTime :number}
|
101
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :datetime
|
102
|
+
INTEGRATION_DB.create_table!(:items){File :number}
|
103
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :blob
|
104
|
+
INTEGRATION_DB.create_table!(:items){TrueClass :number}
|
105
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :boolean
|
106
|
+
INTEGRATION_DB.create_table!(:items){FalseClass :number}
|
107
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :boolean
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
if INTEGRATION_DB.respond_to?(:indexes)
|
113
|
+
describe "Database index parsing" do
|
114
|
+
after do
|
115
|
+
INTEGRATION_DB.drop_table(:items)
|
116
|
+
end
|
117
|
+
|
118
|
+
specify "should parse indexes into a hash" do
|
119
|
+
INTEGRATION_DB.create_table!(:items){Integer :n; Integer :a}
|
120
|
+
INTEGRATION_DB.indexes(:items).should == {}
|
121
|
+
INTEGRATION_DB.add_index(:items, :n)
|
122
|
+
INTEGRATION_DB.indexes(:items).should == {:items_n_index=>{:columns=>[:n], :unique=>false}}
|
123
|
+
INTEGRATION_DB.drop_index(:items, :n)
|
124
|
+
INTEGRATION_DB.indexes(:items).should == {}
|
125
|
+
INTEGRATION_DB.add_index(:items, :n, :unique=>true, :name=>:blah_blah_index)
|
126
|
+
INTEGRATION_DB.indexes(:items).should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}}
|
127
|
+
INTEGRATION_DB.add_index(:items, [:n, :a])
|
128
|
+
INTEGRATION_DB.indexes(:items).should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}, :items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
|
129
|
+
INTEGRATION_DB.drop_index(:items, :n, :name=>:blah_blah_index)
|
130
|
+
INTEGRATION_DB.indexes(:items).should == {:items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
|
131
|
+
INTEGRATION_DB.drop_index(:items, [:n, :a])
|
132
|
+
INTEGRATION_DB.indexes(:items).should == {}
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "should not include a primary key index" do
|
136
|
+
INTEGRATION_DB.create_table!(:items){primary_key :n}
|
137
|
+
INTEGRATION_DB.indexes(:items).should == {}
|
138
|
+
INTEGRATION_DB.create_table!(:items){Integer :n; Integer :a; primary_key [:n, :a]}
|
139
|
+
INTEGRATION_DB.indexes(:items).should == {}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "Database schema modifiers" do
|
145
|
+
before do
|
146
|
+
@db = INTEGRATION_DB
|
147
|
+
@ds = @db[:items]
|
148
|
+
clear_sqls
|
149
|
+
end
|
150
|
+
after do
|
151
|
+
@db.drop_table(:items) if @db.table_exists?(:items)
|
152
|
+
end
|
153
|
+
|
154
|
+
specify "should create tables correctly" do
|
155
|
+
@db.create_table!(:items){Integer :number}
|
156
|
+
@db.table_exists?(:items).should == true
|
157
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
158
|
+
@ds.insert([10])
|
159
|
+
@ds.columns!.should == [:number]
|
160
|
+
end
|
161
|
+
|
162
|
+
specify "should rename tables correctly" do
|
163
|
+
@db.drop_table(:items) rescue nil
|
164
|
+
@db.create_table!(:items2){Integer :number}
|
165
|
+
@db.rename_table(:items2, :items)
|
166
|
+
@db.table_exists?(:items).should == true
|
167
|
+
@db.table_exists?(:items2).should == false
|
168
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
169
|
+
@ds.insert([10])
|
170
|
+
@ds.columns!.should == [:number]
|
171
|
+
end
|
172
|
+
|
173
|
+
specify "should allow creating indexes with tables" do
|
174
|
+
@db.create_table!(:items){Integer :number; index :number}
|
175
|
+
@db.table_exists?(:items).should == true
|
176
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
177
|
+
@ds.insert([10])
|
178
|
+
@ds.columns!.should == [:number]
|
179
|
+
end
|
180
|
+
|
181
|
+
specify "should handle foreign keys correctly when creating tables" do
|
182
|
+
@db.create_table!(:items) do
|
183
|
+
primary_key :id
|
184
|
+
foreign_key :item_id, :items
|
185
|
+
unique [:item_id, :id]
|
186
|
+
foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
|
187
|
+
end
|
188
|
+
@db.table_exists?(:items).should == true
|
189
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
190
|
+
@ds.columns!.should == [:id, :item_id]
|
191
|
+
end
|
192
|
+
|
193
|
+
specify "should add columns to tables correctly" do
|
194
|
+
@db.create_table!(:items){Integer :number}
|
195
|
+
@ds.insert(:number=>10)
|
196
|
+
@db.alter_table(:items){add_column :name, :text}
|
197
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name]
|
198
|
+
@ds.columns!.should == [:number, :name]
|
199
|
+
@ds.all.should == [{:number=>10, :name=>nil}]
|
200
|
+
end
|
201
|
+
|
202
|
+
cspecify "should add primary key columns to tables correctly", :h2 do
|
203
|
+
@db.create_table!(:items){Integer :number}
|
204
|
+
@ds.insert(:number=>10)
|
205
|
+
@db.alter_table(:items){add_primary_key :id}
|
206
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :id]
|
207
|
+
@ds.columns!.should == [:number, :id]
|
208
|
+
@ds.map(:number).should == [10]
|
209
|
+
end
|
210
|
+
|
211
|
+
specify "should add foreign key columns to tables correctly" do
|
212
|
+
@db.create_table!(:items){primary_key :id}
|
213
|
+
i = @ds.insert
|
214
|
+
@db.alter_table(:items){add_foreign_key :item_id, :items}
|
215
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
216
|
+
@ds.columns!.should == [:id, :item_id]
|
217
|
+
@ds.all.should == [{:id=>i, :item_id=>nil}]
|
218
|
+
end
|
219
|
+
|
220
|
+
specify "should rename columns correctly" do
|
221
|
+
@db.create_table!(:items){Integer :id}
|
222
|
+
@ds.insert(:id=>10)
|
223
|
+
@db.alter_table(:items){rename_column :id, :id2}
|
224
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id2]
|
225
|
+
@ds.columns!.should == [:id2]
|
226
|
+
@ds.all.should == [{:id2=>10}]
|
227
|
+
end
|
228
|
+
|
229
|
+
specify "should rename columns with defaults correctly" do
|
230
|
+
@db.create_table!(:items){String :n, :default=>'blah'}
|
231
|
+
@ds.insert
|
232
|
+
@db.alter_table(:items){rename_column :n, :n2}
|
233
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:n2]
|
234
|
+
@ds.columns!.should == [:n2]
|
235
|
+
@ds.insert
|
236
|
+
@ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
|
237
|
+
end
|
238
|
+
|
239
|
+
cspecify "should rename columns with not null constraints", [:mysql, :mysql] do
|
240
|
+
@db.create_table!(:items){String :n, :null=>false}
|
241
|
+
@ds.insert(:n=>'blah')
|
242
|
+
@db.alter_table(:items){rename_column :n, :n2}
|
243
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:n2]
|
244
|
+
@ds.columns!.should == [:n2]
|
245
|
+
@ds.insert(:n2=>'blah')
|
246
|
+
@ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
|
247
|
+
proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
|
248
|
+
end
|
249
|
+
|
250
|
+
cspecify "should set column NULL/NOT NULL correctly", [:mysql, :mysql] do
|
251
|
+
@db.create_table!(:items){Integer :id}
|
252
|
+
@ds.insert(:id=>10)
|
253
|
+
@db.alter_table(:items){set_column_allow_null :id, false}
|
254
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
255
|
+
@ds.columns!.should == [:id]
|
256
|
+
proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
|
257
|
+
@db.alter_table(:items){set_column_allow_null :id, true}
|
258
|
+
@ds.insert
|
259
|
+
@ds.all.should == [{:id=>10}, {:id=>nil}]
|
260
|
+
end
|
261
|
+
|
262
|
+
specify "should set column defaults correctly" do
|
263
|
+
@db.create_table!(:items){Integer :id}
|
264
|
+
@ds.insert(:id=>10)
|
265
|
+
@db.alter_table(:items){set_column_default :id, 20}
|
266
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
267
|
+
@ds.columns!.should == [:id]
|
268
|
+
@ds.insert
|
269
|
+
@ds.all.should == [{:id=>10}, {:id=>20}]
|
270
|
+
end
|
271
|
+
|
272
|
+
specify "should set column types correctly" do
|
273
|
+
@db.create_table!(:items){Integer :id}
|
274
|
+
@ds.insert(:id=>10)
|
275
|
+
@db.alter_table(:items){set_column_type :id, String}
|
276
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
277
|
+
@ds.columns!.should == [:id]
|
278
|
+
@ds.insert(:id=>20)
|
279
|
+
@ds.all.should == [{:id=>"10"}, {:id=>"20"}]
|
280
|
+
end
|
281
|
+
|
282
|
+
cspecify "should add unique constraints and foreign key table constraints correctly", :sqlite do
|
283
|
+
@db.create_table!(:items){Integer :id; Integer :item_id}
|
284
|
+
@db.alter_table(:items) do
|
285
|
+
add_unique_constraint [:item_id, :id]
|
286
|
+
add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
|
287
|
+
end
|
288
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
289
|
+
@ds.columns!.should == [:id, :item_id]
|
290
|
+
end
|
291
|
+
|
292
|
+
cspecify "should remove columns from tables correctly", :h2, :mssql do
|
293
|
+
@db.create_table!(:items) do
|
294
|
+
primary_key :id
|
295
|
+
String :name
|
296
|
+
Integer :number
|
297
|
+
foreign_key :item_id, :items
|
298
|
+
end
|
299
|
+
@ds.insert(:number=>10)
|
300
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number, :item_id]
|
301
|
+
@ds.columns!.should == [:id, :name, :number, :item_id]
|
302
|
+
@db.drop_column(:items, :number)
|
303
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :item_id]
|
304
|
+
@ds.columns!.should == [:id, :name, :item_id]
|
305
|
+
@db.drop_column(:items, :name)
|
306
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
307
|
+
@ds.columns!.should == [:id, :item_id]
|
308
|
+
@db.drop_column(:items, :item_id)
|
309
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
310
|
+
@ds.columns!.should == [:id]
|
311
|
+
end
|
312
|
+
|
313
|
+
specify "should remove multiple columns in a single alter_table block" do
|
314
|
+
@db.create_table!(:items) do
|
315
|
+
primary_key :id
|
316
|
+
String :name
|
317
|
+
Integer :number
|
318
|
+
end
|
319
|
+
@ds.insert(:number=>10)
|
320
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number]
|
321
|
+
@ds.columns!.should == [:id, :name, :number]
|
322
|
+
@db.alter_table(:items) do
|
323
|
+
drop_column :name
|
324
|
+
drop_column :number
|
325
|
+
end
|
326
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
327
|
+
@ds.columns!.should == [:id]
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
if INTEGRATION_DB.respond_to?(:tables)
|
332
|
+
describe "Database#tables" do
|
333
|
+
before do
|
334
|
+
class ::String
|
335
|
+
@@xxxxx = 0
|
336
|
+
def xxxxx
|
337
|
+
"xxxxx#{@@xxxxx += 1}"
|
338
|
+
end
|
339
|
+
end
|
340
|
+
@iom = INTEGRATION_DB.identifier_output_method
|
341
|
+
@iim = INTEGRATION_DB.identifier_input_method
|
342
|
+
clear_sqls
|
343
|
+
end
|
344
|
+
after do
|
345
|
+
INTEGRATION_DB.identifier_output_method = @iom
|
346
|
+
INTEGRATION_DB.identifier_input_method = @iim
|
347
|
+
end
|
348
|
+
|
349
|
+
specify "should return an array of symbols" do
|
350
|
+
ts = INTEGRATION_DB.tables
|
351
|
+
ts.should be_a_kind_of(Array)
|
352
|
+
ts.each{|t| t.should be_a_kind_of(Symbol)}
|
353
|
+
end
|
354
|
+
|
355
|
+
specify "should respect the database's identifier_output_method" do
|
356
|
+
INTEGRATION_DB.identifier_output_method = :xxxxx
|
357
|
+
INTEGRATION_DB.identifier_input_method = :xxxxx
|
358
|
+
INTEGRATION_DB.tables.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|