colincasey-sequel 2.10.0 → 2.10.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -1
- data/doc/advanced_associations.rdoc +614 -0
- data/doc/cheat_sheet.rdoc +223 -0
- data/doc/dataset_filtering.rdoc +158 -0
- data/doc/prepared_statements.rdoc +104 -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.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/schema.rdoc +29 -0
- data/doc/sharding.rdoc +113 -0
- data/lib/sequel.rb +1 -0
- data/lib/sequel_core/adapters/ado.rb +89 -0
- data/lib/sequel_core/adapters/db2.rb +143 -0
- data/lib/sequel_core/adapters/dbi.rb +112 -0
- data/lib/sequel_core/adapters/do/mysql.rb +38 -0
- data/lib/sequel_core/adapters/do/postgres.rb +92 -0
- data/lib/sequel_core/adapters/do/sqlite.rb +31 -0
- data/lib/sequel_core/adapters/do.rb +205 -0
- data/lib/sequel_core/adapters/firebird.rb +298 -0
- data/lib/sequel_core/adapters/informix.rb +85 -0
- data/lib/sequel_core/adapters/jdbc/h2.rb +69 -0
- data/lib/sequel_core/adapters/jdbc/mysql.rb +66 -0
- data/lib/sequel_core/adapters/jdbc/oracle.rb +23 -0
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +113 -0
- data/lib/sequel_core/adapters/jdbc/sqlite.rb +43 -0
- data/lib/sequel_core/adapters/jdbc.rb +491 -0
- data/lib/sequel_core/adapters/mysql.rb +369 -0
- data/lib/sequel_core/adapters/odbc.rb +174 -0
- data/lib/sequel_core/adapters/openbase.rb +68 -0
- data/lib/sequel_core/adapters/oracle.rb +107 -0
- data/lib/sequel_core/adapters/postgres.rb +456 -0
- data/lib/sequel_core/adapters/shared/ms_access.rb +110 -0
- data/lib/sequel_core/adapters/shared/mssql.rb +102 -0
- data/lib/sequel_core/adapters/shared/mysql.rb +325 -0
- data/lib/sequel_core/adapters/shared/oracle.rb +61 -0
- data/lib/sequel_core/adapters/shared/postgres.rb +715 -0
- data/lib/sequel_core/adapters/shared/progress.rb +31 -0
- data/lib/sequel_core/adapters/shared/sqlite.rb +265 -0
- data/lib/sequel_core/adapters/sqlite.rb +248 -0
- data/lib/sequel_core/connection_pool.rb +258 -0
- data/lib/sequel_core/core_ext.rb +217 -0
- data/lib/sequel_core/core_sql.rb +202 -0
- data/lib/sequel_core/database/schema.rb +164 -0
- data/lib/sequel_core/database.rb +691 -0
- data/lib/sequel_core/dataset/callback.rb +13 -0
- data/lib/sequel_core/dataset/convenience.rb +237 -0
- data/lib/sequel_core/dataset/pagination.rb +96 -0
- data/lib/sequel_core/dataset/prepared_statements.rb +220 -0
- data/lib/sequel_core/dataset/query.rb +41 -0
- data/lib/sequel_core/dataset/schema.rb +15 -0
- data/lib/sequel_core/dataset/sql.rb +1010 -0
- data/lib/sequel_core/dataset/stored_procedures.rb +75 -0
- data/lib/sequel_core/dataset/unsupported.rb +43 -0
- data/lib/sequel_core/dataset.rb +511 -0
- data/lib/sequel_core/deprecated.rb +26 -0
- data/lib/sequel_core/exceptions.rb +44 -0
- data/lib/sequel_core/migration.rb +212 -0
- data/lib/sequel_core/object_graph.rb +230 -0
- data/lib/sequel_core/pretty_table.rb +71 -0
- data/lib/sequel_core/schema/generator.rb +320 -0
- data/lib/sequel_core/schema/sql.rb +325 -0
- data/lib/sequel_core/schema.rb +2 -0
- data/lib/sequel_core/sql.rb +887 -0
- data/lib/sequel_core/version.rb +11 -0
- data/lib/sequel_core.rb +172 -0
- data/lib/sequel_model/association_reflection.rb +267 -0
- data/lib/sequel_model/associations.rb +499 -0
- data/lib/sequel_model/base.rb +523 -0
- data/lib/sequel_model/caching.rb +82 -0
- data/lib/sequel_model/dataset_methods.rb +26 -0
- data/lib/sequel_model/eager_loading.rb +370 -0
- data/lib/sequel_model/exceptions.rb +7 -0
- data/lib/sequel_model/hooks.rb +101 -0
- data/lib/sequel_model/inflector.rb +281 -0
- data/lib/sequel_model/plugins.rb +62 -0
- data/lib/sequel_model/record.rb +568 -0
- data/lib/sequel_model/schema.rb +49 -0
- data/lib/sequel_model/validations.rb +429 -0
- data/lib/sequel_model.rb +91 -0
- data/spec/adapters/ado_spec.rb +46 -0
- data/spec/adapters/firebird_spec.rb +376 -0
- data/spec/adapters/informix_spec.rb +96 -0
- data/spec/adapters/mysql_spec.rb +881 -0
- data/spec/adapters/oracle_spec.rb +244 -0
- data/spec/adapters/postgres_spec.rb +687 -0
- data/spec/adapters/spec_helper.rb +10 -0
- data/spec/adapters/sqlite_spec.rb +555 -0
- data/spec/integration/dataset_test.rb +134 -0
- data/spec/integration/eager_loader_test.rb +696 -0
- data/spec/integration/prepared_statement_test.rb +130 -0
- data/spec/integration/schema_test.rb +180 -0
- data/spec/integration/spec_helper.rb +58 -0
- data/spec/integration/type_test.rb +96 -0
- data/spec/rcov.opts +6 -0
- data/spec/sequel_core/connection_pool_spec.rb +526 -0
- data/spec/sequel_core/core_ext_spec.rb +156 -0
- data/spec/sequel_core/core_sql_spec.rb +522 -0
- data/spec/sequel_core/database_spec.rb +1188 -0
- data/spec/sequel_core/dataset_spec.rb +3481 -0
- data/spec/sequel_core/expression_filters_spec.rb +363 -0
- data/spec/sequel_core/migration_spec.rb +261 -0
- data/spec/sequel_core/object_graph_spec.rb +272 -0
- data/spec/sequel_core/pretty_table_spec.rb +58 -0
- data/spec/sequel_core/schema_generator_spec.rb +167 -0
- data/spec/sequel_core/schema_spec.rb +780 -0
- data/spec/sequel_core/spec_helper.rb +55 -0
- data/spec/sequel_core/version_spec.rb +7 -0
- data/spec/sequel_model/association_reflection_spec.rb +93 -0
- data/spec/sequel_model/associations_spec.rb +1767 -0
- data/spec/sequel_model/base_spec.rb +419 -0
- data/spec/sequel_model/caching_spec.rb +215 -0
- data/spec/sequel_model/dataset_methods_spec.rb +78 -0
- data/spec/sequel_model/eager_loading_spec.rb +1165 -0
- data/spec/sequel_model/hooks_spec.rb +485 -0
- data/spec/sequel_model/inflector_spec.rb +119 -0
- data/spec/sequel_model/model_spec.rb +588 -0
- data/spec/sequel_model/plugins_spec.rb +80 -0
- data/spec/sequel_model/record_spec.rb +1184 -0
- data/spec/sequel_model/schema_spec.rb +90 -0
- data/spec/sequel_model/spec_helper.rb +78 -0
- data/spec/sequel_model/validations_spec.rb +1067 -0
- data/spec/spec.opts +0 -0
- data/spec/spec_config.rb.example +10 -0
- metadata +177 -3
@@ -0,0 +1,130 @@
|
|
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 placeholder literal strings" do
|
28
|
+
@ds.filter("number = ?", @ds.ba(:$n)).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
|
29
|
+
end
|
30
|
+
|
31
|
+
specify "should support datasets with static sql and placeholders" do
|
32
|
+
INTEGRATION_DB["SELECT * FROM items WHERE number = ?", @ds.ba(:$n)].call(:select, :n=>10).should == [{:id=>1, :number=>10}]
|
33
|
+
end
|
34
|
+
|
35
|
+
specify "should support subselects" do
|
36
|
+
@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}]
|
37
|
+
end
|
38
|
+
|
39
|
+
specify "should support subselects with literal strings" do
|
40
|
+
@ds.filter(:id=>:$i, :number=>@ds.select(:number).filter("number = ?", @ds.ba(:$n))).call(:select, :n=>10, :i=>1).should == [{:id=>1, :number=>10}]
|
41
|
+
end
|
42
|
+
|
43
|
+
specify "should support subselects with static sql and placeholders" do
|
44
|
+
@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}]
|
45
|
+
end
|
46
|
+
|
47
|
+
specify "should support subselects of subselects" do
|
48
|
+
@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}]
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "should support bound variables with insert" do
|
52
|
+
@ds.call(:insert, {:n=>20, :i=>100}, :id=>@ds.ba(:$i), :number=>@ds.ba(:$n))
|
53
|
+
@ds.count.should == 2
|
54
|
+
@ds.order(:id).all.should == [{:id=>1, :number=>10}, {:id=>100, :number=>20}]
|
55
|
+
end
|
56
|
+
|
57
|
+
specify "should have insert return primary key value when using bound arguments" do
|
58
|
+
@ds.call(:insert, {:n=>20}, :number=>@ds.ba(:$n)).should == 2
|
59
|
+
@ds.filter(:id=>2).first[:number].should == 20
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "should support bound variables with delete" do
|
63
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:delete, :n=>10).should == 1
|
64
|
+
@ds.count.should == 0
|
65
|
+
end
|
66
|
+
|
67
|
+
specify "should support bound variables with update" do
|
68
|
+
@ds.filter(:number=>@ds.ba(:$n)).call(:update, {:n=>10, :nn=>20}, :number=>:number+@ds.ba(:$nn)).should == 1
|
69
|
+
@ds.all.should == [{:id=>1, :number=>30}]
|
70
|
+
end
|
71
|
+
|
72
|
+
specify "should support prepared statements with select, first, and all" do
|
73
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:select, :select_n)
|
74
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
|
75
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:all, :select_n)
|
76
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
|
77
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:first, :select_n)
|
78
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == {:id=>1, :number=>10}
|
79
|
+
if INTEGRATION_DB.uri =~ /jdbc:sqlite:/
|
80
|
+
# Work around for open prepared statements on a table not allowing the
|
81
|
+
# dropping of a table when using SQLite over JDBC
|
82
|
+
INTEGRATION_DB.synchronize{|c| c.prepared_statements[:select_n][1].close}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
specify "should support prepared statements with insert" do
|
87
|
+
@ds.prepare(:insert, :insert_n, :id=>@ds.ba(:$i), :number=>@ds.ba(:$n))
|
88
|
+
INTEGRATION_DB.call(:insert_n, :n=>20, :i=>100)
|
89
|
+
@ds.count.should == 2
|
90
|
+
@ds.order(:id).all.should == [{:id=>1, :number=>10}, {:id=>100, :number=>20}]
|
91
|
+
end
|
92
|
+
|
93
|
+
specify "should have insert return primary key value when using prepared statements" do
|
94
|
+
@ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
|
95
|
+
INTEGRATION_DB.call(:insert_n, :n=>20).should == 2
|
96
|
+
@ds.filter(:id=>2).first[:number].should == 20
|
97
|
+
end
|
98
|
+
|
99
|
+
specify "should support prepared statements with delete" do
|
100
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:delete, :delete_n)
|
101
|
+
INTEGRATION_DB.call(:delete_n, :n=>10).should == 1
|
102
|
+
@ds.count.should == 0
|
103
|
+
end
|
104
|
+
|
105
|
+
specify "should support prepared statements with update" do
|
106
|
+
@ds.filter(:number=>@ds.ba(:$n)).prepare(:update, :update_n, :number=>:number+@ds.ba(:$nn))
|
107
|
+
INTEGRATION_DB.call(:update_n, :n=>10, :nn=>20).should == 1
|
108
|
+
@ds.all.should == [{:id=>1, :number=>30}]
|
109
|
+
end
|
110
|
+
|
111
|
+
specify "model datasets should return model instances when using select, all, and first with bound variables" do
|
112
|
+
@c.filter(:number=>@ds.ba(:$n)).call(:select, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
113
|
+
@c.filter(:number=>@ds.ba(:$n)).call(:all, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
114
|
+
@c.filter(:number=>@ds.ba(:$n)).call(:first, :n=>10).should == @c.load(:id=>1, :number=>10)
|
115
|
+
end
|
116
|
+
|
117
|
+
specify "model datasets should return model instances when using select, all, and first with prepared statements" do
|
118
|
+
@c.filter(:number=>@ds.ba(:$n)).prepare(:select, :select_n)
|
119
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
120
|
+
@c.filter(:number=>@ds.ba(:$n)).prepare(:all, :select_n)
|
121
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
|
122
|
+
@c.filter(:number=>@ds.ba(:$n)).prepare(:first, :select_n)
|
123
|
+
INTEGRATION_DB.call(:select_n, :n=>10).should == @c.load(:id=>1, :number=>10)
|
124
|
+
if INTEGRATION_DB.uri =~ /jdbc:sqlite:/
|
125
|
+
# Work around for open prepared statements on a table not allowing the
|
126
|
+
# dropping of a table when using SQLite over JDBC
|
127
|
+
INTEGRATION_DB.synchronize{|c| c.prepared_statements[:select_n][1].close}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,180 @@
|
|
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(nil, :reload=>true)[:items].should be_a_kind_of(Array)
|
24
|
+
INTEGRATION_DB.schema(:items, :reload=>true).first.first.should == :number
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "should be a hash with table_names as symbols" do
|
28
|
+
INTEGRATION_DB.create_table!(:items){integer :number}
|
29
|
+
schema = INTEGRATION_DB.schema(nil, :reload=>true)
|
30
|
+
schema.should be_a_kind_of(Hash)
|
31
|
+
schema[:items].should_not == nil
|
32
|
+
end
|
33
|
+
|
34
|
+
specify "should not issue an sql query if the schema has been loaded unless :reload is true" do
|
35
|
+
INTEGRATION_DB.create_table!(:items){integer :number}
|
36
|
+
INTEGRATION_DB.schema(nil, :reload=>true)
|
37
|
+
clear_sqls
|
38
|
+
INTEGRATION_DB.schema
|
39
|
+
sqls_should_be
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "should give the same result for a single table regardless of whether schema was called for a single table" do
|
43
|
+
INTEGRATION_DB.create_table!(:items){integer :number}
|
44
|
+
INTEGRATION_DB.schema(:items, :reload=>true).should == INTEGRATION_DB.schema(nil, :reload=>true)[:items]
|
45
|
+
end
|
46
|
+
|
47
|
+
specify "should raise an error when the table doesn't exist" do
|
48
|
+
proc{INTEGRATION_DB.schema(:no_table)}.should raise_error(Sequel::Error)
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "should return the schema correctly" do
|
52
|
+
INTEGRATION_DB.create_table!(:items){integer :number}
|
53
|
+
schema = INTEGRATION_DB.schema(:items, :reload=>true)
|
54
|
+
schema.should be_a_kind_of(Array)
|
55
|
+
schema.length.should == 1
|
56
|
+
col = schema.first
|
57
|
+
col.should be_a_kind_of(Array)
|
58
|
+
col.length.should == 2
|
59
|
+
col.first.should == :number
|
60
|
+
col_info = col.last
|
61
|
+
col_info.should be_a_kind_of(Hash)
|
62
|
+
col_info[:type].should == :integer
|
63
|
+
clear_sqls
|
64
|
+
INTEGRATION_DB.schema(:items)
|
65
|
+
sqls_should_be
|
66
|
+
end
|
67
|
+
|
68
|
+
specify "should parse primary keys from the schema properly" do
|
69
|
+
INTEGRATION_DB.create_table!(:items){integer :number}
|
70
|
+
INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == []
|
71
|
+
INTEGRATION_DB.create_table!(:items){primary_key :number}
|
72
|
+
INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == [:number]
|
73
|
+
INTEGRATION_DB.create_table!(:items){integer :number1; integer :number2; primary_key [:number1, :number2]}
|
74
|
+
INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == [:number1, :number2]
|
75
|
+
end
|
76
|
+
|
77
|
+
specify "should parse NULL/NOT NULL from the schema properly" do
|
78
|
+
INTEGRATION_DB.create_table!(:items){integer :number, :null=>true}
|
79
|
+
INTEGRATION_DB.schema(:items).first.last[:allow_null].should == true
|
80
|
+
INTEGRATION_DB.create_table!(:items){integer :number, :null=>false}
|
81
|
+
INTEGRATION_DB.schema(:items).first.last[:allow_null].should == false
|
82
|
+
end
|
83
|
+
|
84
|
+
specify "should parse defaults from the schema properly" do
|
85
|
+
INTEGRATION_DB.create_table!(:items){integer :number}
|
86
|
+
INTEGRATION_DB.schema(:items).first.last[:default].should == nil
|
87
|
+
INTEGRATION_DB.create_table!(:items){integer :number, :default=>0}
|
88
|
+
INTEGRATION_DB.schema(:items).first.last[:default].to_s.should == "0"
|
89
|
+
INTEGRATION_DB.create_table!(:items){varchar :a, :default=>"blah", :size=>4}
|
90
|
+
INTEGRATION_DB.schema(:items).first.last[:default].gsub(/::character varying\z/, '').gsub("'", '').should == "blah"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "Database schema modifiers" do
|
96
|
+
before do
|
97
|
+
INTEGRATION_DB.create_table!(:items){integer :number}
|
98
|
+
@ds = INTEGRATION_DB[:items]
|
99
|
+
@ds.insert([10])
|
100
|
+
clear_sqls
|
101
|
+
end
|
102
|
+
after do
|
103
|
+
INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
|
104
|
+
end
|
105
|
+
|
106
|
+
specify "should create tables correctly" do
|
107
|
+
INTEGRATION_DB.table_exists?(:items).should == true
|
108
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
109
|
+
@ds.columns!.should == [:number]
|
110
|
+
end
|
111
|
+
|
112
|
+
specify "should add columns to tables correctly" do
|
113
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
114
|
+
@ds.columns!.should == [:number]
|
115
|
+
INTEGRATION_DB.alter_table(:items){add_column :name, :text}
|
116
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name]
|
117
|
+
@ds.columns!.should == [:number, :name]
|
118
|
+
unless INTEGRATION_DB.url =~ /sqlite/
|
119
|
+
INTEGRATION_DB.alter_table(:items){add_primary_key :id}
|
120
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name, :id]
|
121
|
+
@ds.columns!.should == [:number, :name, :id]
|
122
|
+
INTEGRATION_DB.alter_table(:items){add_foreign_key :item_id, :items}
|
123
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name, :id, :item_id]
|
124
|
+
@ds.columns!.should == [:number, :name, :id, :item_id]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
specify "should remove columns from tables correctly" do
|
129
|
+
INTEGRATION_DB.create_table!(:items) do
|
130
|
+
primary_key :id
|
131
|
+
text :name
|
132
|
+
integer :number
|
133
|
+
foreign_key :item_id, :items
|
134
|
+
end
|
135
|
+
@ds.insert(:number=>10)
|
136
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number, :item_id]
|
137
|
+
@ds.columns!.should == [:id, :name, :number, :item_id]
|
138
|
+
INTEGRATION_DB.drop_column(:items, :number)
|
139
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :item_id]
|
140
|
+
@ds.columns!.should == [:id, :name, :item_id]
|
141
|
+
INTEGRATION_DB.drop_column(:items, :name)
|
142
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
143
|
+
@ds.columns!.should == [:id, :item_id]
|
144
|
+
INTEGRATION_DB.drop_column(:items, :item_id)
|
145
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
146
|
+
@ds.columns!.should == [:id]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
if INTEGRATION_DB.respond_to?(:tables)
|
151
|
+
describe "Database#tables" do
|
152
|
+
before do
|
153
|
+
class ::String
|
154
|
+
@@xxxxx = 0
|
155
|
+
def xxxxx
|
156
|
+
"xxxxx#{@@xxxxx += 1}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
@iom = INTEGRATION_DB.identifier_output_method
|
160
|
+
@iim = INTEGRATION_DB.identifier_input_method
|
161
|
+
clear_sqls
|
162
|
+
end
|
163
|
+
after do
|
164
|
+
INTEGRATION_DB.identifier_output_method = @iom
|
165
|
+
INTEGRATION_DB.identifier_input_method = @iim
|
166
|
+
end
|
167
|
+
|
168
|
+
specify "should return an array of symbols" do
|
169
|
+
ts = INTEGRATION_DB.tables
|
170
|
+
ts.should be_a_kind_of(Array)
|
171
|
+
ts.each{|t| t.should be_a_kind_of(Symbol)}
|
172
|
+
end
|
173
|
+
|
174
|
+
specify "should respect the database's identifier_output_method" do
|
175
|
+
INTEGRATION_DB.identifier_output_method = :xxxxx
|
176
|
+
INTEGRATION_DB.identifier_input_method = :xxxxx
|
177
|
+
INTEGRATION_DB.tables.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
unless Object.const_defined?('Sequel')
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
|
4
|
+
require 'sequel'
|
5
|
+
end
|
6
|
+
begin
|
7
|
+
require File.join(File.dirname(__FILE__), '../spec_config.rb')
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
$sqls = []
|
12
|
+
def clear_sqls
|
13
|
+
$sqls.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
class Spec::Example::ExampleGroup
|
17
|
+
def start_logging
|
18
|
+
require 'logger'
|
19
|
+
INTEGRATION_DB.loggers << Logger.new(STDOUT)
|
20
|
+
end
|
21
|
+
def stop_logging
|
22
|
+
INTEGRATION_DB.loggers.clear
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
if defined?(INTEGRATION_DB) || defined?(INTEGRATION_URL) || ENV['SEQUEL_INTEGRATION_URL']
|
27
|
+
unless defined?(INTEGRATION_DB)
|
28
|
+
url = defined?(INTEGRATION_URL) ? INTEGRATION_URL : ENV['SEQUEL_INTEGRATION_URL']
|
29
|
+
INTEGRATION_DB = Sequel.connect(url)
|
30
|
+
#INTEGRATION_DB.instance_variable_set(:@server_version, 80100)
|
31
|
+
end
|
32
|
+
class Spec::Example::ExampleGroup
|
33
|
+
def sqls_should_be(*args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
else
|
37
|
+
sql_logger = Object.new
|
38
|
+
def sql_logger.info(str)
|
39
|
+
$sqls << str
|
40
|
+
end
|
41
|
+
INTEGRATION_DB = Sequel.sqlite('', :loggers=>[sql_logger], :quote_identifiers=>false)
|
42
|
+
class Spec::Example::ExampleGroup
|
43
|
+
def sqls_should_be(*sqls)
|
44
|
+
sqls.zip($sqls).each do |should_be, is|
|
45
|
+
case should_be
|
46
|
+
when String
|
47
|
+
is.should == should_be
|
48
|
+
when Regexp
|
49
|
+
is.should =~ should_be
|
50
|
+
else
|
51
|
+
raise ArgumentError, "need String or RegExp"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
$sqls.length.should == sqls.length
|
55
|
+
clear_sqls
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe "Supported types" do
|
4
|
+
def create_items_table_with_column(name, type, opts={})
|
5
|
+
INTEGRATION_DB.create_table!(:items){column name, type, opts}
|
6
|
+
INTEGRATION_DB[:items]
|
7
|
+
end
|
8
|
+
|
9
|
+
specify "should support casting correctly" do
|
10
|
+
ds = create_items_table_with_column(:number, Integer)
|
11
|
+
ds.insert(:number => 1)
|
12
|
+
ds.select(:number.cast_string.as(:n)).map(:n).should == %w'1'
|
13
|
+
ds = create_items_table_with_column(:name, String)
|
14
|
+
ds.insert(:name=> '1')
|
15
|
+
ds.select(:name.cast_numeric.as(:n)).map(:n).should == [1]
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should support NULL correctly" do
|
19
|
+
ds = create_items_table_with_column(:number, Integer)
|
20
|
+
ds.insert(:number => nil)
|
21
|
+
ds.all.should == [{:number=>nil}]
|
22
|
+
end
|
23
|
+
|
24
|
+
specify "should support generic integer type" do
|
25
|
+
ds = create_items_table_with_column(:number, Integer)
|
26
|
+
ds.insert(:number => 2)
|
27
|
+
ds.all.should == [{:number=>2}]
|
28
|
+
end
|
29
|
+
|
30
|
+
specify "should support generic fixnum type" do
|
31
|
+
ds = create_items_table_with_column(:number, Fixnum)
|
32
|
+
ds.insert(:number => 2)
|
33
|
+
ds.all.should == [{:number=>2}]
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "should support generic bignum type" do
|
37
|
+
ds = create_items_table_with_column(:number, Bignum)
|
38
|
+
ds.insert(:number => 2**34)
|
39
|
+
ds.all.should == [{:number=>2**34}]
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "should support generic float type" do
|
43
|
+
ds = create_items_table_with_column(:number, Float)
|
44
|
+
ds.insert(:number => 2.1)
|
45
|
+
ds.all.should == [{:number=>2.1}]
|
46
|
+
end
|
47
|
+
|
48
|
+
specify "should support generic numeric type" do
|
49
|
+
ds = create_items_table_with_column(:number, Numeric, :size=>[15, 10])
|
50
|
+
ds.insert(:number => BigDecimal.new('2.123456789'))
|
51
|
+
ds.all.should == [{:number=>BigDecimal.new('2.123456789')}]
|
52
|
+
ds = create_items_table_with_column(:number, BigDecimal, :size=>[15, 10])
|
53
|
+
ds.insert(:number => BigDecimal.new('2.123456789'))
|
54
|
+
ds.all.should == [{:number=>BigDecimal.new('2.123456789')}]
|
55
|
+
end
|
56
|
+
|
57
|
+
specify "should support generic string type" do
|
58
|
+
ds = create_items_table_with_column(:name, String)
|
59
|
+
ds.insert(:name => 'Test User')
|
60
|
+
ds.all.should == [{:name=>'Test User'}]
|
61
|
+
end
|
62
|
+
|
63
|
+
specify "should support generic date type" do
|
64
|
+
ds = create_items_table_with_column(:dat, Date)
|
65
|
+
d = Date.today
|
66
|
+
ds.insert(:dat => d)
|
67
|
+
ds.first[:dat].should == d
|
68
|
+
end
|
69
|
+
|
70
|
+
specify "should support generic datetime type" do
|
71
|
+
ds = create_items_table_with_column(:tim, DateTime)
|
72
|
+
t = DateTime.now
|
73
|
+
ds.insert(:tim => t)
|
74
|
+
ds.first[:tim].strftime('%Y%m%d%H%M%S').should == t.strftime('%Y%m%d%H%M%S')
|
75
|
+
ds = create_items_table_with_column(:tim, Time)
|
76
|
+
t = Time.now
|
77
|
+
ds.insert(:tim => t)
|
78
|
+
ds.first[:tim].strftime('%Y%m%d%H%M%S').should == t.strftime('%Y%m%d%H%M%S')
|
79
|
+
end
|
80
|
+
|
81
|
+
specify "should support generic file type" do
|
82
|
+
ds = create_items_table_with_column(:name, File)
|
83
|
+
ds.insert(:name => ("a\0"*300).to_sequel_blob)
|
84
|
+
ds.all.should == [{:name=>("a\0"*300).to_sequel_blob}]
|
85
|
+
ds.first[:name].should be_a_kind_of(::Sequel::SQL::Blob)
|
86
|
+
end
|
87
|
+
|
88
|
+
specify "should support generic boolean type" do
|
89
|
+
ds = create_items_table_with_column(:number, TrueClass)
|
90
|
+
ds.insert(:number => true)
|
91
|
+
ds.all.should == [{:number=>true}]
|
92
|
+
ds = create_items_table_with_column(:number, FalseClass)
|
93
|
+
ds.insert(:number => true)
|
94
|
+
ds.all.should == [{:number=>true}]
|
95
|
+
end
|
96
|
+
end
|