sequel_core 2.2.0 → 3.8.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.
- metadata +30 -101
- data/CHANGELOG +0 -1519
- data/COPYING +0 -19
- data/README +0 -313
- data/Rakefile +0 -158
- data/bin/sequel +0 -117
- data/doc/cheat_sheet.rdoc +0 -225
- data/doc/dataset_filtering.rdoc +0 -182
- data/lib/sequel_core.rb +0 -136
- data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -68
- data/lib/sequel_core/adapters/ado.rb +0 -90
- data/lib/sequel_core/adapters/db2.rb +0 -160
- data/lib/sequel_core/adapters/dbi.rb +0 -127
- data/lib/sequel_core/adapters/informix.rb +0 -89
- data/lib/sequel_core/adapters/jdbc.rb +0 -110
- data/lib/sequel_core/adapters/mysql.rb +0 -486
- data/lib/sequel_core/adapters/odbc.rb +0 -167
- data/lib/sequel_core/adapters/odbc_mssql.rb +0 -106
- data/lib/sequel_core/adapters/openbase.rb +0 -76
- data/lib/sequel_core/adapters/oracle.rb +0 -182
- data/lib/sequel_core/adapters/postgres.rb +0 -560
- data/lib/sequel_core/adapters/sqlite.rb +0 -270
- data/lib/sequel_core/connection_pool.rb +0 -194
- data/lib/sequel_core/core_ext.rb +0 -197
- data/lib/sequel_core/core_sql.rb +0 -184
- data/lib/sequel_core/database.rb +0 -462
- data/lib/sequel_core/database/schema.rb +0 -156
- data/lib/sequel_core/dataset.rb +0 -457
- data/lib/sequel_core/dataset/callback.rb +0 -13
- data/lib/sequel_core/dataset/convenience.rb +0 -245
- data/lib/sequel_core/dataset/pagination.rb +0 -96
- data/lib/sequel_core/dataset/query.rb +0 -41
- data/lib/sequel_core/dataset/schema.rb +0 -15
- data/lib/sequel_core/dataset/sql.rb +0 -889
- data/lib/sequel_core/deprecated.rb +0 -26
- data/lib/sequel_core/exceptions.rb +0 -42
- data/lib/sequel_core/migration.rb +0 -187
- data/lib/sequel_core/object_graph.rb +0 -216
- data/lib/sequel_core/pretty_table.rb +0 -71
- data/lib/sequel_core/schema.rb +0 -2
- data/lib/sequel_core/schema/generator.rb +0 -239
- data/lib/sequel_core/schema/sql.rb +0 -326
- data/lib/sequel_core/sql.rb +0 -812
- data/lib/sequel_core/worker.rb +0 -68
- data/spec/adapters/informix_spec.rb +0 -96
- data/spec/adapters/mysql_spec.rb +0 -765
- data/spec/adapters/oracle_spec.rb +0 -222
- data/spec/adapters/postgres_spec.rb +0 -441
- data/spec/adapters/sqlite_spec.rb +0 -413
- data/spec/connection_pool_spec.rb +0 -363
- data/spec/core_ext_spec.rb +0 -156
- data/spec/core_sql_spec.rb +0 -427
- data/spec/database_spec.rb +0 -963
- data/spec/dataset_spec.rb +0 -2933
- data/spec/expression_filters_spec.rb +0 -316
- data/spec/migration_spec.rb +0 -261
- data/spec/object_graph_spec.rb +0 -230
- data/spec/pretty_table_spec.rb +0 -58
- data/spec/rcov.opts +0 -6
- data/spec/schema_generator_spec.rb +0 -122
- data/spec/schema_spec.rb +0 -422
- data/spec/spec.opts +0 -0
- data/spec/spec_config.rb +0 -7
- data/spec/spec_config.rb.example +0 -8
- data/spec/spec_helper.rb +0 -55
- data/spec/worker_spec.rb +0 -96
@@ -1,222 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '../spec_helper.rb')
|
2
|
-
|
3
|
-
unless defined?(ORACLE_DB)
|
4
|
-
ORACLE_DB = Sequel.connect('oracle://hr:hr@localhost/XE')
|
5
|
-
end
|
6
|
-
|
7
|
-
if ORACLE_DB.table_exists?(:items)
|
8
|
-
ORACLE_DB.drop_table :items
|
9
|
-
end
|
10
|
-
ORACLE_DB.create_table :items do
|
11
|
-
varchar2 :name, :size => 50
|
12
|
-
number :value, :size => 38
|
13
|
-
|
14
|
-
index :value
|
15
|
-
end
|
16
|
-
|
17
|
-
if ORACLE_DB.table_exists?(:books)
|
18
|
-
ORACLE_DB.drop_table :books
|
19
|
-
end
|
20
|
-
ORACLE_DB.create_table :books do
|
21
|
-
number :id, :size => 38
|
22
|
-
varchar2 :title, :size => 50
|
23
|
-
number :category_id, :size => 38
|
24
|
-
end
|
25
|
-
|
26
|
-
if ORACLE_DB.table_exists?(:categories)
|
27
|
-
ORACLE_DB.drop_table :categories
|
28
|
-
end
|
29
|
-
ORACLE_DB.create_table :categories do
|
30
|
-
number :id, :size => 38
|
31
|
-
varchar2 :cat_name, :size => 50
|
32
|
-
end
|
33
|
-
|
34
|
-
context "An Oracle database" do
|
35
|
-
specify "should provide disconnect functionality" do
|
36
|
-
ORACLE_DB.execute("select user from dual")
|
37
|
-
ORACLE_DB.pool.size.should == 1
|
38
|
-
ORACLE_DB.disconnect
|
39
|
-
ORACLE_DB.pool.size.should == 0
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context "An Oracle dataset" do
|
44
|
-
setup do
|
45
|
-
@d = ORACLE_DB[:items]
|
46
|
-
@d.delete # remove all records
|
47
|
-
end
|
48
|
-
|
49
|
-
specify "should return the correct record count" do
|
50
|
-
@d.count.should == 0
|
51
|
-
@d << {:name => 'abc', :value => 123}
|
52
|
-
@d << {:name => 'abc', :value => 456}
|
53
|
-
@d << {:name => 'def', :value => 789}
|
54
|
-
@d.count.should == 3
|
55
|
-
end
|
56
|
-
|
57
|
-
specify "should return the correct records" do
|
58
|
-
@d.to_a.should == []
|
59
|
-
@d << {:name => 'abc', :value => 123}
|
60
|
-
@d << {:name => 'abc', :value => 456}
|
61
|
-
@d << {:name => 'def', :value => 789}
|
62
|
-
|
63
|
-
@d.order(:value).to_a.should == [
|
64
|
-
{:name => 'abc', :value => 123},
|
65
|
-
{:name => 'abc', :value => 456},
|
66
|
-
{:name => 'def', :value => 789}
|
67
|
-
]
|
68
|
-
|
69
|
-
@d.select(:name).uniq.order_by(:name).to_a.should == [
|
70
|
-
{:name => 'abc'},
|
71
|
-
{:name => 'def'}
|
72
|
-
]
|
73
|
-
|
74
|
-
@d.order(:value.DESC).limit(1).to_a.should == [
|
75
|
-
{:name => 'def', :value => 789}
|
76
|
-
]
|
77
|
-
|
78
|
-
@d.filter(:name => 'abc').to_a.should == [
|
79
|
-
{:name => 'abc', :value => 123},
|
80
|
-
{:name => 'abc', :value => 456}
|
81
|
-
]
|
82
|
-
|
83
|
-
@d.order(:value.DESC).filter(:name => 'abc').to_a.should == [
|
84
|
-
{:name => 'abc', :value => 456},
|
85
|
-
{:name => 'abc', :value => 123}
|
86
|
-
]
|
87
|
-
|
88
|
-
@d.filter(:name => 'abc').limit(1).to_a.should == [
|
89
|
-
{:name => 'abc', :value => 123}
|
90
|
-
]
|
91
|
-
|
92
|
-
@d.filter(:name => 'abc').order(:value.DESC).limit(1).to_a.should == [
|
93
|
-
{:name => 'abc', :value => 456}
|
94
|
-
]
|
95
|
-
|
96
|
-
@d.filter(:name => 'abc').order(:value).limit(1).to_a.should == [
|
97
|
-
{:name => 'abc', :value => 123}
|
98
|
-
]
|
99
|
-
|
100
|
-
@d.order(:value).limit(1).to_a.should == [
|
101
|
-
{:name => 'abc', :value => 123}
|
102
|
-
]
|
103
|
-
|
104
|
-
@d.order(:value).limit(1, 1).to_a.should == [
|
105
|
-
{:name => 'abc', :value => 456}
|
106
|
-
]
|
107
|
-
|
108
|
-
@d.order(:value).limit(1, 2).to_a.should == [
|
109
|
-
{:name => 'def', :value => 789}
|
110
|
-
]
|
111
|
-
|
112
|
-
@d.avg(:value).to_i.should == (789+123+456)/3
|
113
|
-
|
114
|
-
@d.max(:value).to_i.should == 789
|
115
|
-
|
116
|
-
@d.select(:name, :AVG[:value]).filter(:name => 'abc').group(:name).to_a.should == [
|
117
|
-
{:name => 'abc', :"avg(value)" => (456+123)/2.0}
|
118
|
-
]
|
119
|
-
|
120
|
-
@d.select(:AVG[:value]).group(:name).order(:name).limit(1).to_a.should == [
|
121
|
-
{:"avg(value)" => (456+123)/2.0}
|
122
|
-
]
|
123
|
-
|
124
|
-
@d.select(:name, :AVG[:value]).group(:name).order(:name).to_a.should == [
|
125
|
-
{:name => 'abc', :"avg(value)" => (456+123)/2.0},
|
126
|
-
{:name => 'def', :"avg(value)" => 789*1.0}
|
127
|
-
]
|
128
|
-
|
129
|
-
@d.select(:name, :AVG[:value]).group(:name).order(:name).to_a.should == [
|
130
|
-
{:name => 'abc', :"avg(value)" => (456+123)/2.0},
|
131
|
-
{:name => 'def', :"avg(value)" => 789*1.0}
|
132
|
-
]
|
133
|
-
|
134
|
-
@d.select(:name, :AVG[:value]).group(:name).having(:name => ['abc', 'def']).order(:name).to_a.should == [
|
135
|
-
{:name => 'abc', :"avg(value)" => (456+123)/2.0},
|
136
|
-
{:name => 'def', :"avg(value)" => 789*1.0}
|
137
|
-
]
|
138
|
-
|
139
|
-
@d.select(:name, :value).filter(:name => 'abc').union(@d.select(:name, :value).filter(:name => 'def')).order(:value).to_a.should == [
|
140
|
-
{:name => 'abc', :value => 123},
|
141
|
-
{:name => 'abc', :value => 456},
|
142
|
-
{:name => 'def', :value => 789}
|
143
|
-
]
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
|
-
specify "should update records correctly" do
|
148
|
-
@d << {:name => 'abc', :value => 123}
|
149
|
-
@d << {:name => 'abc', :value => 456}
|
150
|
-
@d << {:name => 'def', :value => 789}
|
151
|
-
@d.filter(:name => 'abc').update(:value => 530)
|
152
|
-
|
153
|
-
# the third record should stay the same
|
154
|
-
# floating-point precision bullshit
|
155
|
-
@d[:name => 'def'][:value].should == 789
|
156
|
-
@d.filter(:value => 530).count.should == 2
|
157
|
-
end
|
158
|
-
|
159
|
-
specify "should delete records correctly" do
|
160
|
-
@d << {:name => 'abc', :value => 123}
|
161
|
-
@d << {:name => 'abc', :value => 456}
|
162
|
-
@d << {:name => 'def', :value => 789}
|
163
|
-
@d.filter(:name => 'abc').delete
|
164
|
-
|
165
|
-
@d.count.should == 1
|
166
|
-
@d.first[:name].should == 'def'
|
167
|
-
end
|
168
|
-
|
169
|
-
specify "should be able to literalize booleans" do
|
170
|
-
proc {@d.literal(true)}.should_not raise_error
|
171
|
-
proc {@d.literal(false)}.should_not raise_error
|
172
|
-
end
|
173
|
-
|
174
|
-
specify "should support transactions" do
|
175
|
-
ORACLE_DB.transaction do
|
176
|
-
@d << {:name => 'abc', :value => 1}
|
177
|
-
end
|
178
|
-
|
179
|
-
@d.count.should == 1
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
context "Joined Oracle dataset" do
|
184
|
-
setup do
|
185
|
-
@d1 = ORACLE_DB[:books]
|
186
|
-
@d1.delete # remove all records
|
187
|
-
@d1 << {:id => 1, :title => 'aaa', :category_id => 100}
|
188
|
-
@d1 << {:id => 2, :title => 'bbb', :category_id => 100}
|
189
|
-
@d1 << {:id => 3, :title => 'ccc', :category_id => 101}
|
190
|
-
@d1 << {:id => 4, :title => 'ddd', :category_id => 102}
|
191
|
-
|
192
|
-
@d2 = ORACLE_DB[:categories]
|
193
|
-
@d2.delete # remove all records
|
194
|
-
@d2 << {:id => 100, :cat_name => 'ruby'}
|
195
|
-
@d2 << {:id => 101, :cat_name => 'rails'}
|
196
|
-
end
|
197
|
-
|
198
|
-
specify "should return correct result" do
|
199
|
-
@d1.join(:categories, :id => :category_id).select(:books__id, :title, :cat_name).order(:books__id).to_a.should == [
|
200
|
-
{:id => 1, :title => 'aaa', :cat_name => 'ruby'},
|
201
|
-
{:id => 2, :title => 'bbb', :cat_name => 'ruby'},
|
202
|
-
{:id => 3, :title => 'ccc', :cat_name => 'rails'}
|
203
|
-
]
|
204
|
-
|
205
|
-
@d1.join(:categories, :id => :category_id).select(:books__id, :title, :cat_name).order(:books__id).limit(2, 1).to_a.should == [
|
206
|
-
{:id => 2, :title => 'bbb', :cat_name => 'ruby'},
|
207
|
-
{:id => 3, :title => 'ccc', :cat_name => 'rails'},
|
208
|
-
]
|
209
|
-
|
210
|
-
@d1.left_outer_join(:categories, :id => :category_id).select(:books__id, :title, :cat_name).order(:books__id).to_a.should == [
|
211
|
-
{:id => 1, :title => 'aaa', :cat_name => 'ruby'},
|
212
|
-
{:id => 2, :title => 'bbb', :cat_name => 'ruby'},
|
213
|
-
{:id => 3, :title => 'ccc', :cat_name => 'rails'},
|
214
|
-
{:id => 4, :title => 'ddd', :cat_name => nil}
|
215
|
-
]
|
216
|
-
|
217
|
-
@d1.left_outer_join(:categories, :id => :category_id).select(:books__id, :title, :cat_name).order(:books__id.DESC).limit(2, 0).to_a.should == [
|
218
|
-
{:id => 4, :title => 'ddd', :cat_name => nil},
|
219
|
-
{:id => 3, :title => 'ccc', :cat_name => 'rails'}
|
220
|
-
]
|
221
|
-
end
|
222
|
-
end
|
@@ -1,441 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '../spec_helper.rb')
|
2
|
-
|
3
|
-
unless defined?(POSTGRES_DB)
|
4
|
-
POSTGRES_URL = 'postgres://postgres:postgres@localhost:5432/reality_spec' unless defined? POSTGRES_URL
|
5
|
-
POSTGRES_DB = Sequel.connect(ENV['SEQUEL_PG_SPEC_DB']||POSTGRES_URL)
|
6
|
-
end
|
7
|
-
|
8
|
-
POSTGRES_DB.create_table! :test do
|
9
|
-
text :name
|
10
|
-
integer :value, :index => true
|
11
|
-
end
|
12
|
-
POSTGRES_DB.create_table! :test2 do
|
13
|
-
text :name
|
14
|
-
integer :value
|
15
|
-
end
|
16
|
-
POSTGRES_DB.create_table! :test3 do
|
17
|
-
integer :value
|
18
|
-
timestamp :time
|
19
|
-
end
|
20
|
-
POSTGRES_DB.create_table! :test4 do
|
21
|
-
varchar :name, :size => 20
|
22
|
-
bytea :value
|
23
|
-
end
|
24
|
-
|
25
|
-
context "A PostgreSQL database" do
|
26
|
-
setup do
|
27
|
-
@db = POSTGRES_DB
|
28
|
-
end
|
29
|
-
|
30
|
-
specify "should provide disconnect functionality" do
|
31
|
-
@db.tables
|
32
|
-
@db.pool.size.should == 1
|
33
|
-
@db.disconnect
|
34
|
-
@db.pool.size.should == 0
|
35
|
-
end
|
36
|
-
|
37
|
-
specify "should provide the server version" do
|
38
|
-
@db.server_version.should > 70000
|
39
|
-
end
|
40
|
-
|
41
|
-
specify "should raise Sequel::Error on error" do
|
42
|
-
proc{@db << "SELECT 1 + 'a'"}.should raise_error(Sequel::Error)
|
43
|
-
end
|
44
|
-
|
45
|
-
specify "should correctly parse the schema" do
|
46
|
-
@db.schema(:test3, :reload=>true).should == [
|
47
|
-
[:value, {:type=>:integer, :allow_null=>true, :max_chars=>nil, :default=>nil, :db_type=>"integer", :numeric_precision=>32}],
|
48
|
-
[:time, {:type=>:datetime, :allow_null=>true, :max_chars=>nil, :default=>nil, :db_type=>"timestamp without time zone", :numeric_precision=>nil}]
|
49
|
-
]
|
50
|
-
@db.schema(:test4, :reload=>true).should == [
|
51
|
-
[:name, {:type=>:string, :allow_null=>true, :max_chars=>20, :default=>nil, :db_type=>"character varying", :numeric_precision=>nil}],
|
52
|
-
[:value, {:type=>:blob, :allow_null=>true, :max_chars=>nil, :default=>nil, :db_type=>"bytea", :numeric_precision=>nil}]
|
53
|
-
]
|
54
|
-
end
|
55
|
-
|
56
|
-
specify "should get the schema all database tables if no table name is used" do
|
57
|
-
@db.schema(:test3, :reload=>true).should == @db.schema(nil, :reload=>true)[:test3]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context "A PostgreSQL dataset" do
|
62
|
-
setup do
|
63
|
-
@d = POSTGRES_DB[:test]
|
64
|
-
@d.delete # remove all records
|
65
|
-
end
|
66
|
-
|
67
|
-
specify "should return the correct record count" do
|
68
|
-
@d.count.should == 0
|
69
|
-
@d << {:name => 'abc', :value => 123}
|
70
|
-
@d << {:name => 'abc', :value => 456}
|
71
|
-
@d << {:name => 'def', :value => 789}
|
72
|
-
@d.count.should == 3
|
73
|
-
end
|
74
|
-
|
75
|
-
specify "should return the correct records" do
|
76
|
-
@d.to_a.should == []
|
77
|
-
@d << {:name => 'abc', :value => 123}
|
78
|
-
@d << {:name => 'abc', :value => 456}
|
79
|
-
@d << {:name => 'def', :value => 789}
|
80
|
-
|
81
|
-
@d.order(:value).to_a.should == [
|
82
|
-
{:name => 'abc', :value => 123},
|
83
|
-
{:name => 'abc', :value => 456},
|
84
|
-
{:name => 'def', :value => 789}
|
85
|
-
]
|
86
|
-
end
|
87
|
-
|
88
|
-
specify "should update records correctly" do
|
89
|
-
@d << {:name => 'abc', :value => 123}
|
90
|
-
@d << {:name => 'abc', :value => 456}
|
91
|
-
@d << {:name => 'def', :value => 789}
|
92
|
-
@d.filter(:name => 'abc').update(:value => 530)
|
93
|
-
|
94
|
-
# the third record should stay the same
|
95
|
-
# floating-point precision bullshit
|
96
|
-
@d[:name => 'def'][:value].should == 789
|
97
|
-
@d.filter(:value => 530).count.should == 2
|
98
|
-
end
|
99
|
-
|
100
|
-
specify "should delete records correctly" do
|
101
|
-
@d << {:name => 'abc', :value => 123}
|
102
|
-
@d << {:name => 'abc', :value => 456}
|
103
|
-
@d << {:name => 'def', :value => 789}
|
104
|
-
@d.filter(:name => 'abc').delete
|
105
|
-
|
106
|
-
@d.count.should == 1
|
107
|
-
@d.first[:name].should == 'def'
|
108
|
-
end
|
109
|
-
|
110
|
-
specify "should be able to literalize booleans" do
|
111
|
-
proc {@d.literal(true)}.should_not raise_error
|
112
|
-
proc {@d.literal(false)}.should_not raise_error
|
113
|
-
end
|
114
|
-
|
115
|
-
specify "should quote columns and tables using double quotes if quoting identifiers" do
|
116
|
-
@d.quote_identifiers = true
|
117
|
-
@d.select(:name).sql.should == \
|
118
|
-
'SELECT "name" FROM "test"'
|
119
|
-
|
120
|
-
@d.select('COUNT(*)'.lit).sql.should == \
|
121
|
-
'SELECT COUNT(*) FROM "test"'
|
122
|
-
|
123
|
-
@d.select(:max[:value]).sql.should == \
|
124
|
-
'SELECT max("value") FROM "test"'
|
125
|
-
|
126
|
-
@d.select(:NOW[]).sql.should == \
|
127
|
-
'SELECT NOW() FROM "test"'
|
128
|
-
|
129
|
-
@d.select(:max[:items__value]).sql.should == \
|
130
|
-
'SELECT max("items"."value") FROM "test"'
|
131
|
-
|
132
|
-
@d.order(:name.desc).sql.should == \
|
133
|
-
'SELECT * FROM "test" ORDER BY "name" DESC'
|
134
|
-
|
135
|
-
@d.select('test.name AS item_name'.lit).sql.should == \
|
136
|
-
'SELECT test.name AS item_name FROM "test"'
|
137
|
-
|
138
|
-
@d.select('"name"'.lit).sql.should == \
|
139
|
-
'SELECT "name" FROM "test"'
|
140
|
-
|
141
|
-
@d.select('max(test."name") AS "max_name"'.lit).sql.should == \
|
142
|
-
'SELECT max(test."name") AS "max_name" FROM "test"'
|
143
|
-
|
144
|
-
@d.select(:test[:abc, 'hello']).sql.should == \
|
145
|
-
"SELECT test(\"abc\", 'hello') FROM \"test\""
|
146
|
-
|
147
|
-
@d.select(:test[:abc__def, 'hello']).sql.should == \
|
148
|
-
"SELECT test(\"abc\".\"def\", 'hello') FROM \"test\""
|
149
|
-
|
150
|
-
@d.select(:test[:abc__def, 'hello'].as(:x2)).sql.should == \
|
151
|
-
"SELECT test(\"abc\".\"def\", 'hello') AS \"x2\" FROM \"test\""
|
152
|
-
|
153
|
-
@d.insert_sql(:value => 333).should == \
|
154
|
-
'INSERT INTO "test" ("value") VALUES (333)'
|
155
|
-
|
156
|
-
@d.insert_sql(:x => :y).should == \
|
157
|
-
'INSERT INTO "test" ("x") VALUES ("y")'
|
158
|
-
end
|
159
|
-
|
160
|
-
specify "should quote fields correctly when reversing the order if quoting identifiers" do
|
161
|
-
@d.quote_identifiers = true
|
162
|
-
@d.reverse_order(:name).sql.should == \
|
163
|
-
'SELECT * FROM "test" ORDER BY "name" DESC'
|
164
|
-
|
165
|
-
@d.reverse_order(:name.desc).sql.should == \
|
166
|
-
'SELECT * FROM "test" ORDER BY "name" ASC'
|
167
|
-
|
168
|
-
@d.reverse_order(:name, :test.desc).sql.should == \
|
169
|
-
'SELECT * FROM "test" ORDER BY "name" DESC, "test" ASC'
|
170
|
-
|
171
|
-
@d.reverse_order(:name.desc, :test).sql.should == \
|
172
|
-
'SELECT * FROM "test" ORDER BY "name" ASC, "test" DESC'
|
173
|
-
end
|
174
|
-
|
175
|
-
specify "should support transactions" do
|
176
|
-
POSTGRES_DB.transaction do
|
177
|
-
@d << {:name => 'abc', :value => 1}
|
178
|
-
end
|
179
|
-
|
180
|
-
@d.count.should == 1
|
181
|
-
end
|
182
|
-
|
183
|
-
specify "should have #transaction yield the connection" do
|
184
|
-
POSTGRES_DB.transaction do |conn|
|
185
|
-
conn.should be_a_kind_of(Sequel::Postgres::Adapter)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
specify "should correctly rollback transactions" do
|
190
|
-
proc do
|
191
|
-
POSTGRES_DB.transaction do
|
192
|
-
@d << {:name => 'abc', :value => 1}
|
193
|
-
raise Interrupt, 'asdf'
|
194
|
-
end
|
195
|
-
end.should raise_error(Interrupt)
|
196
|
-
|
197
|
-
@d.count.should == 0
|
198
|
-
end
|
199
|
-
|
200
|
-
specify "should handle returning inside of the block by committing" do
|
201
|
-
def POSTGRES_DB.ret_commit
|
202
|
-
transaction do
|
203
|
-
self[:test] << {:name => 'abc'}
|
204
|
-
return
|
205
|
-
self[:test] << {:name => 'd'}
|
206
|
-
end
|
207
|
-
end
|
208
|
-
@d.count.should == 0
|
209
|
-
POSTGRES_DB.ret_commit
|
210
|
-
@d.count.should == 1
|
211
|
-
POSTGRES_DB.ret_commit
|
212
|
-
@d.count.should == 2
|
213
|
-
proc do
|
214
|
-
POSTGRES_DB.transaction do
|
215
|
-
raise Interrupt, 'asdf'
|
216
|
-
end
|
217
|
-
end.should raise_error(Interrupt)
|
218
|
-
|
219
|
-
@d.count.should == 2
|
220
|
-
end
|
221
|
-
|
222
|
-
specify "should support nested transactions through savepoints" do
|
223
|
-
POSTGRES_DB.transaction do
|
224
|
-
@d << {:name => '1'}
|
225
|
-
POSTGRES_DB.transaction do
|
226
|
-
@d << {:name => '2'}
|
227
|
-
POSTGRES_DB.transaction do
|
228
|
-
@d << {:name => '3'}
|
229
|
-
raise Sequel::Error::Rollback
|
230
|
-
end
|
231
|
-
@d << {:name => '4'}
|
232
|
-
POSTGRES_DB.transaction do
|
233
|
-
@d << {:name => '6'}
|
234
|
-
POSTGRES_DB.transaction do
|
235
|
-
@d << {:name => '7'}
|
236
|
-
end
|
237
|
-
raise Sequel::Error::Rollback
|
238
|
-
end
|
239
|
-
@d << {:name => '5'}
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
@d.count.should == 4
|
244
|
-
@d.order(:name).map(:name).should == %w{1 2 4 5}
|
245
|
-
end
|
246
|
-
|
247
|
-
specify "should support regexps" do
|
248
|
-
@d << {:name => 'abc', :value => 1}
|
249
|
-
@d << {:name => 'bcd', :value => 2}
|
250
|
-
@d.filter(:name => /bc/).count.should == 2
|
251
|
-
@d.filter(:name => /^bc/).count.should == 1
|
252
|
-
end
|
253
|
-
|
254
|
-
specify "should correctly escape strings" do
|
255
|
-
POSTGRES_DB['SELECT ? AS a', "\\dingo"].get(:a) == "\\dingo"
|
256
|
-
end
|
257
|
-
|
258
|
-
specify "should properly escape binary data" do
|
259
|
-
POSTGRES_DB['SELECT ? AS a', "\1\2\3".to_blob].get(:a) == "\1\2\3"
|
260
|
-
end
|
261
|
-
|
262
|
-
specify "should retrieve binary data as Blob object" do
|
263
|
-
d = POSTGRES_DB[:test4]
|
264
|
-
d << {:name => '123', :value => "\1\2\3".to_blob}
|
265
|
-
retrieved_binary_value = d[:name => '123'][:value]
|
266
|
-
retrieved_binary_value.should be_a_kind_of(::Sequel::SQL::Blob)
|
267
|
-
retrieved_binary_value.should == "\1\2\3"
|
268
|
-
retrieved_binary_value = d[:value => "\1\2\3".to_blob][:value]
|
269
|
-
retrieved_binary_value.should be_a_kind_of(::Sequel::SQL::Blob)
|
270
|
-
retrieved_binary_value.should == "\1\2\3"
|
271
|
-
end
|
272
|
-
|
273
|
-
specify "should properly receive binary data" do
|
274
|
-
POSTGRES_DB['SELECT ?::bytea AS a', "a"].get(:a) == "a"
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
context "A PostgreSQL dataaset with a timestamp field" do
|
279
|
-
setup do
|
280
|
-
@d = POSTGRES_DB[:test3]
|
281
|
-
@d.delete
|
282
|
-
end
|
283
|
-
|
284
|
-
specify "should store milliseconds in time fields" do
|
285
|
-
t = Time.now
|
286
|
-
@d << {:value=>1, :time=>t}
|
287
|
-
@d[:value =>'1'][:time].should == t
|
288
|
-
@d[:value=>'1'][:time].usec.should == t.usec
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
context "A PostgreSQL database" do
|
293
|
-
setup do
|
294
|
-
@db = POSTGRES_DB
|
295
|
-
end
|
296
|
-
|
297
|
-
specify "should support column operations" do
|
298
|
-
@db.create_table!(:test2){text :name; integer :value}
|
299
|
-
@db[:test2] << {}
|
300
|
-
@db[:test2].columns.should == [:name, :value]
|
301
|
-
|
302
|
-
@db.add_column :test2, :xyz, :text, :default => '000'
|
303
|
-
@db[:test2].columns.should == [:name, :value, :xyz]
|
304
|
-
@db[:test2] << {:name => 'mmm', :value => 111}
|
305
|
-
@db[:test2].first[:xyz].should == '000'
|
306
|
-
|
307
|
-
@db[:test2].columns.should == [:name, :value, :xyz]
|
308
|
-
@db.drop_column :test2, :xyz
|
309
|
-
|
310
|
-
@db[:test2].columns.should == [:name, :value]
|
311
|
-
|
312
|
-
@db[:test2].delete
|
313
|
-
@db.add_column :test2, :xyz, :text, :default => '000'
|
314
|
-
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
|
315
|
-
|
316
|
-
@db[:test2].columns.should == [:name, :value, :xyz]
|
317
|
-
@db.rename_column :test2, :xyz, :zyx
|
318
|
-
@db[:test2].columns.should == [:name, :value, :zyx]
|
319
|
-
@db[:test2].first[:zyx].should == 'qqqq'
|
320
|
-
|
321
|
-
@db.add_column :test2, :xyz, :float
|
322
|
-
@db[:test2].delete
|
323
|
-
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 56.78}
|
324
|
-
@db.set_column_type :test2, :xyz, :integer
|
325
|
-
|
326
|
-
@db[:test2].first[:xyz].should == 57
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
context "A PostgreSQL database" do
|
331
|
-
setup do
|
332
|
-
end
|
333
|
-
|
334
|
-
specify "should support fulltext indexes" do
|
335
|
-
g = Sequel::Schema::Generator.new(POSTGRES_DB) do
|
336
|
-
text :title
|
337
|
-
text :body
|
338
|
-
full_text_index [:title, :body]
|
339
|
-
end
|
340
|
-
POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
|
341
|
-
"CREATE TABLE posts (title text, body text)",
|
342
|
-
"CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector(title || body))"
|
343
|
-
]
|
344
|
-
end
|
345
|
-
|
346
|
-
specify "should support fulltext indexes with a specific language" do
|
347
|
-
g = Sequel::Schema::Generator.new(POSTGRES_DB) do
|
348
|
-
text :title
|
349
|
-
text :body
|
350
|
-
full_text_index [:title, :body], :language => 'french'
|
351
|
-
end
|
352
|
-
POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
|
353
|
-
"CREATE TABLE posts (title text, body text)",
|
354
|
-
"CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('french', title || body))"
|
355
|
-
]
|
356
|
-
end
|
357
|
-
|
358
|
-
specify "should support full_text_search" do
|
359
|
-
POSTGRES_DB[:posts].full_text_search(:title, 'ruby').sql.should ==
|
360
|
-
"SELECT * FROM posts WHERE (to_tsvector(title) @@ to_tsquery('ruby'))"
|
361
|
-
|
362
|
-
POSTGRES_DB[:posts].full_text_search([:title, :body], ['ruby', 'sequel']).sql.should ==
|
363
|
-
"SELECT * FROM posts WHERE (to_tsvector(title || body) @@ to_tsquery('ruby | sequel'))"
|
364
|
-
|
365
|
-
POSTGRES_DB[:posts].full_text_search(:title, 'ruby', :language => 'french').sql.should ==
|
366
|
-
"SELECT * FROM posts WHERE (to_tsvector('french', title) @@ to_tsquery('french', 'ruby'))"
|
367
|
-
end
|
368
|
-
|
369
|
-
specify "should support spatial indexes" do
|
370
|
-
g = Sequel::Schema::Generator.new(POSTGRES_DB) do
|
371
|
-
geometry :geom
|
372
|
-
spatial_index [:geom]
|
373
|
-
end
|
374
|
-
POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
|
375
|
-
"CREATE TABLE posts (geom geometry)",
|
376
|
-
"CREATE INDEX posts_geom_index ON posts USING gist (geom)"
|
377
|
-
]
|
378
|
-
end
|
379
|
-
|
380
|
-
specify "should support indexes with index type" do
|
381
|
-
g = Sequel::Schema::Generator.new(POSTGRES_DB) do
|
382
|
-
varchar :title, :size => 5
|
383
|
-
index :title, :type => 'hash'
|
384
|
-
end
|
385
|
-
POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
|
386
|
-
"CREATE TABLE posts (title varchar(5))",
|
387
|
-
"CREATE INDEX posts_title_index ON posts USING hash (title)"
|
388
|
-
]
|
389
|
-
end
|
390
|
-
|
391
|
-
specify "should support unique indexes with index type" do
|
392
|
-
g = Sequel::Schema::Generator.new(POSTGRES_DB) do
|
393
|
-
varchar :title, :size => 5
|
394
|
-
index :title, :type => 'hash', :unique => true
|
395
|
-
end
|
396
|
-
POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
|
397
|
-
"CREATE TABLE posts (title varchar(5))",
|
398
|
-
"CREATE UNIQUE INDEX posts_title_index ON posts USING hash (title)"
|
399
|
-
]
|
400
|
-
end
|
401
|
-
|
402
|
-
specify "should support partial indexes" do
|
403
|
-
g = Sequel::Schema::Generator.new(POSTGRES_DB) do
|
404
|
-
varchar :title, :size => 5
|
405
|
-
index :title, :where => {:something => 5}
|
406
|
-
end
|
407
|
-
POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
|
408
|
-
"CREATE TABLE posts (title varchar(5))",
|
409
|
-
"CREATE INDEX posts_title_index ON posts (title) WHERE (something = 5)"
|
410
|
-
]
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
context "Postgres::Dataset#multi_insert_sql / #import" do
|
415
|
-
setup do
|
416
|
-
@ds = POSTGRES_DB[:test]
|
417
|
-
end
|
418
|
-
|
419
|
-
specify "should return separate insert statements if server_version < 80200" do
|
420
|
-
@ds.db.meta_def(:server_version) {80199}
|
421
|
-
|
422
|
-
@ds.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
|
423
|
-
'INSERT INTO test (x, y) VALUES (1, 2)',
|
424
|
-
'INSERT INTO test (x, y) VALUES (3, 4)'
|
425
|
-
]
|
426
|
-
end
|
427
|
-
|
428
|
-
specify "should a single insert statement if server_version >= 80200" do
|
429
|
-
@ds.db.meta_def(:server_version) {80200}
|
430
|
-
|
431
|
-
@ds.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
|
432
|
-
'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)'
|
433
|
-
]
|
434
|
-
|
435
|
-
@ds.db.meta_def(:server_version) {80201}
|
436
|
-
|
437
|
-
@ds.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
|
438
|
-
'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)'
|
439
|
-
]
|
440
|
-
end
|
441
|
-
end
|