sequel 4.14.0 → 4.15.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.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/README.rdoc +3 -3
- data/Rakefile +1 -1
- data/doc/opening_databases.rdoc +20 -2
- data/doc/release_notes/4.15.0.txt +56 -0
- data/doc/testing.rdoc +10 -4
- data/lib/sequel/adapters/fdbsql.rb +285 -0
- data/lib/sequel/adapters/informix.rb +15 -0
- data/lib/sequel/adapters/jdbc/fdbsql.rb +65 -0
- data/lib/sequel/adapters/mock.rb +1 -0
- data/lib/sequel/adapters/shared/fdbsql.rb +550 -0
- data/lib/sequel/adapters/shared/postgres.rb +23 -10
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +10 -3
- data/lib/sequel/dataset/placeholder_literalizer.rb +7 -0
- data/lib/sequel/extensions/date_arithmetic.rb +5 -0
- data/lib/sequel/extensions/migration.rb +2 -2
- data/lib/sequel/extensions/pg_array.rb +15 -1
- data/lib/sequel/extensions/pg_json.rb +3 -0
- data/lib/sequel/extensions/pg_json_ops.rb +4 -4
- data/lib/sequel/extensions/schema_dumper.rb +9 -1
- data/lib/sequel/model/associations.rb +70 -21
- data/lib/sequel/plugins/active_model.rb +7 -2
- data/lib/sequel/plugins/many_through_many.rb +1 -0
- data/lib/sequel/plugins/pg_array_associations.rb +2 -1
- data/lib/sequel/plugins/split_values.rb +64 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/fdbsql_spec.rb +429 -0
- data/spec/adapters/informix_spec.rb +6 -0
- data/spec/adapters/postgres_spec.rb +49 -1
- data/spec/adapters/spec_helper.rb +6 -1
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/core/placeholder_literalizer_spec.rb +10 -0
- data/spec/extensions/date_arithmetic_spec.rb +7 -0
- data/spec/extensions/many_through_many_spec.rb +14 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/pg_array_associations_spec.rb +9 -0
- data/spec/extensions/pg_json_ops_spec.rb +4 -8
- data/spec/extensions/schema_dumper_spec.rb +9 -0
- data/spec/extensions/spec_helper.rb +3 -0
- data/spec/extensions/split_values_spec.rb +22 -0
- data/spec/integration/database_test.rb +1 -1
- data/spec/integration/dataset_test.rb +1 -1
- data/spec/integration/eager_loader_test.rb +1 -1
- data/spec/integration/plugin_test.rb +3 -2
- data/spec/integration/prepared_statement_test.rb +3 -3
- data/spec/integration/schema_test.rb +3 -3
- data/spec/integration/spec_helper.rb +6 -1
- data/spec/integration/timezone_test.rb +1 -1
- data/spec/model/association_reflection_spec.rb +29 -0
- data/spec/model/associations_spec.rb +36 -0
- data/spec/model/eager_loading_spec.rb +14 -0
- data/spec/model/spec_helper.rb +3 -0
- data/spec/rspec_helper.rb +4 -0
- metadata +10 -2
@@ -240,7 +240,7 @@ module Sequel
|
|
240
240
|
|
241
241
|
# The primary key of the associated model.
|
242
242
|
def primary_key
|
243
|
-
cached_fetch(:primary_key){associated_class.primary_key}
|
243
|
+
cached_fetch(:primary_key){associated_class.primary_key || raise(Error, "no primary key specified for #{associated_class.inspect}")}
|
244
244
|
end
|
245
245
|
|
246
246
|
# The method to call to get value of the primary key of the associated model.
|
@@ -301,6 +301,7 @@ module Sequel
|
|
301
301
|
name = opts[:name]
|
302
302
|
model = self
|
303
303
|
pk = opts[:eager_loader_key] = opts[:primary_key] ||= model.primary_key
|
304
|
+
raise(Error, "no primary key specified for #{inspect}") unless pk
|
304
305
|
opts[:key] = opts.default_key unless opts.has_key?(:key)
|
305
306
|
key = opts[:key]
|
306
307
|
key_column = opts[:key_column] ||= opts[:key]
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
|
+
# The split_values plugin splits the values hash retreived from the
|
4
|
+
# database, and moves keys from the values hash that are not columns
|
5
|
+
# in the model's dataset to a separate hash. This makes it so the
|
6
|
+
# values hash only stores columns from the model's dataset.
|
7
|
+
#
|
8
|
+
# Among other things, this allows you to save model objects even if
|
9
|
+
# they were retrieved with additional columns, and have equality
|
10
|
+
# comparisons with other instances not care about non-column values.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# class Album < Sequel::Model
|
15
|
+
# plugin :split_values
|
16
|
+
# end
|
17
|
+
# a1 = Album[1]
|
18
|
+
# a2 = Album.select_append(Sequel.as(true, :exists))[1]
|
19
|
+
# a1.name # => 'Album Name'
|
20
|
+
# a2.name # => 'Album Name'
|
21
|
+
# a1[:exists] # => nil
|
22
|
+
# a2[:exists] # => true
|
23
|
+
# a1 == a2 # => true
|
24
|
+
# a2.values # => {:id=>1, :name=>'Album Name'}
|
25
|
+
# a2.save # Works
|
26
|
+
#
|
27
|
+
# Usage:
|
28
|
+
#
|
29
|
+
# # Make all model subclass instances split values
|
30
|
+
# # (called before loading subclasses)
|
31
|
+
# Sequel::Model.plugin :split_values
|
32
|
+
#
|
33
|
+
# # Make the Album class split values
|
34
|
+
# Album.plugin :split_values
|
35
|
+
module SplitValues
|
36
|
+
module ClassMethods
|
37
|
+
# Split the noncolumn values when creating a new object retrieved from
|
38
|
+
# the database.
|
39
|
+
def call(_)
|
40
|
+
super.split_noncolumn_values
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module InstanceMethods
|
45
|
+
# If there isn't an entry in the values hash, but there is a noncolumn_values
|
46
|
+
# hash, look in that hash for the value.
|
47
|
+
def [](k)
|
48
|
+
super || (@noncolumn_values[k] if !@values.has_key?(k) && @noncolumn_values)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Check all entries in the values hash. If any of the keys are not columns,
|
52
|
+
# move the entry into the noncolumn_values hash.
|
53
|
+
def split_noncolumn_values
|
54
|
+
@values.keys.each do |k|
|
55
|
+
unless columns.include?(k)
|
56
|
+
(@noncolumn_values ||= {})[k] = @values.delete(k)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
self
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/sequel/version.rb
CHANGED
@@ -3,7 +3,7 @@ module Sequel
|
|
3
3
|
MAJOR = 4
|
4
4
|
# The minor version of Sequel. Bumped for every non-patch level
|
5
5
|
# release, generally around once a month.
|
6
|
-
MINOR =
|
6
|
+
MINOR = 15
|
7
7
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
8
8
|
# releases that fix regressions from previous versions.
|
9
9
|
TINY = 0
|
@@ -0,0 +1,429 @@
|
|
1
|
+
SEQUEL_ADAPTER_TEST = :fdbsql
|
2
|
+
|
3
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
4
|
+
|
5
|
+
describe 'Fdbsql' do
|
6
|
+
describe 'Database' do
|
7
|
+
before(:all) do
|
8
|
+
@db = DB
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'schema_parsing' do
|
12
|
+
after do
|
13
|
+
@db.drop_table?(:test)
|
14
|
+
end
|
15
|
+
|
16
|
+
specify 'without primary key' do
|
17
|
+
@db.create_table(:test) do
|
18
|
+
text :name
|
19
|
+
int :value
|
20
|
+
end
|
21
|
+
schema = DB.schema(:test, :reload => true)
|
22
|
+
schema.count.should == 2
|
23
|
+
schema[0][0].should == :name
|
24
|
+
schema[1][0].should == :value
|
25
|
+
schema.each {|col| col[1][:primary_key].should == nil}
|
26
|
+
end
|
27
|
+
|
28
|
+
specify 'with one primary key' do
|
29
|
+
@db.create_table(:test) do
|
30
|
+
text :name
|
31
|
+
primary_key :id
|
32
|
+
end
|
33
|
+
schema = DB.schema(:test, :reload => true)
|
34
|
+
schema.count.should == 2
|
35
|
+
id_col = schema[0]
|
36
|
+
name_col = schema[1]
|
37
|
+
name_col[0].should == :name
|
38
|
+
id_col[0].should == :id
|
39
|
+
name_col[1][:primary_key].should == nil
|
40
|
+
id_col[1][:primary_key].should == true
|
41
|
+
end
|
42
|
+
|
43
|
+
specify 'with multiple primary keys' do
|
44
|
+
@db.create_table(:test) do
|
45
|
+
Integer :id
|
46
|
+
Integer :id2
|
47
|
+
primary_key [:id, :id2]
|
48
|
+
end
|
49
|
+
schema = DB.schema(:test, :reload => true)
|
50
|
+
schema.count.should == 2
|
51
|
+
id_col = schema[0]
|
52
|
+
id2_col = schema[1]
|
53
|
+
id_col[0].should == :id
|
54
|
+
id2_col[0].should == :id2
|
55
|
+
id_col[1][:primary_key].should == true
|
56
|
+
id2_col[1][:primary_key].should == true
|
57
|
+
end
|
58
|
+
|
59
|
+
specify 'with other constraints' do
|
60
|
+
@db.create_table(:test) do
|
61
|
+
primary_key :id
|
62
|
+
Integer :unique, :unique => true
|
63
|
+
end
|
64
|
+
schema = DB.schema(:test, :reload => true)
|
65
|
+
schema.count.should == 2
|
66
|
+
id_col = schema[0]
|
67
|
+
unique_col = schema[1]
|
68
|
+
id_col[0].should == :id
|
69
|
+
unique_col[0].should == :unique
|
70
|
+
id_col[1][:primary_key].should == true
|
71
|
+
unique_col[1][:primary_key].should == nil
|
72
|
+
end
|
73
|
+
after do
|
74
|
+
@db.drop_table?(:other_table)
|
75
|
+
end
|
76
|
+
specify 'with other tables' do
|
77
|
+
@db.create_table(:test) do
|
78
|
+
Integer :id
|
79
|
+
text :name
|
80
|
+
end
|
81
|
+
@db.create_table(:other_table) do
|
82
|
+
primary_key :id
|
83
|
+
varchar :name, :unique => true
|
84
|
+
end
|
85
|
+
schema = DB.schema(:test, :reload => true)
|
86
|
+
schema.count.should == 2
|
87
|
+
schema.each {|col| col[1][:primary_key].should == nil}
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'with explicit schema' do
|
91
|
+
before do
|
92
|
+
@db.create_table(:test) do
|
93
|
+
primary_key :id
|
94
|
+
end
|
95
|
+
@schema = @db['SELECT CURRENT_SCHEMA'].first.values.first
|
96
|
+
@second_schema = @schema + "--2"
|
97
|
+
@db.create_table(Sequel.qualify(@second_schema,:test)) do
|
98
|
+
primary_key :id2
|
99
|
+
Integer :id
|
100
|
+
end
|
101
|
+
end
|
102
|
+
after do
|
103
|
+
@db.drop_table?(Sequel.qualify(@second_schema,:test))
|
104
|
+
@db.drop_table?(:test)
|
105
|
+
end
|
106
|
+
|
107
|
+
specify 'gets info for correct table' do
|
108
|
+
schema = DB.schema(:test, :reload => true, :schema => @second_schema)
|
109
|
+
schema.count.should == 2
|
110
|
+
id2_col = schema[0]
|
111
|
+
id_col = schema[1]
|
112
|
+
id_col[0].should == :id
|
113
|
+
id2_col[0].should == :id2
|
114
|
+
id_col[1][:primary_key].should == nil
|
115
|
+
id2_col[1][:primary_key].should == true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'primary_key' do
|
121
|
+
after do
|
122
|
+
@db.drop_table?(:test)
|
123
|
+
@db.drop_table?(:other_table)
|
124
|
+
end
|
125
|
+
|
126
|
+
specify 'without primary key' do
|
127
|
+
@db.create_table(:test) do
|
128
|
+
text :name
|
129
|
+
int :value
|
130
|
+
end
|
131
|
+
DB.primary_key(:test).should == nil
|
132
|
+
end
|
133
|
+
|
134
|
+
specify 'with one primary key' do
|
135
|
+
@db.create_table(:test) do
|
136
|
+
text :name
|
137
|
+
primary_key :id
|
138
|
+
end
|
139
|
+
DB.primary_key(:test).should == :id
|
140
|
+
end
|
141
|
+
|
142
|
+
specify 'with multiple primary keys' do
|
143
|
+
@db.create_table(:test) do
|
144
|
+
Integer :id
|
145
|
+
Integer :id2
|
146
|
+
primary_key [:id, :id2]
|
147
|
+
end
|
148
|
+
DB.primary_key(:test).should == [:id, :id2]
|
149
|
+
end
|
150
|
+
|
151
|
+
specify 'with other constraints' do
|
152
|
+
@db.create_table(:test) do
|
153
|
+
primary_key :id
|
154
|
+
Integer :unique, :unique => true
|
155
|
+
end
|
156
|
+
DB.primary_key(:test).should == :id
|
157
|
+
end
|
158
|
+
|
159
|
+
specify 'with other tables' do
|
160
|
+
@db.create_table(:test) do
|
161
|
+
Integer :id
|
162
|
+
text :name
|
163
|
+
end
|
164
|
+
@db.create_table(:other_table) do
|
165
|
+
primary_key :id
|
166
|
+
varchar :name, :unique => true
|
167
|
+
end
|
168
|
+
DB.primary_key(:other_table).should == :id
|
169
|
+
end
|
170
|
+
|
171
|
+
specify 'responds to alter table' do
|
172
|
+
@db.create_table(:test) do
|
173
|
+
Integer :id
|
174
|
+
text :name
|
175
|
+
end
|
176
|
+
@db.alter_table(:test) do
|
177
|
+
add_primary_key :quid
|
178
|
+
end
|
179
|
+
DB.primary_key(:test).should == :quid
|
180
|
+
end
|
181
|
+
|
182
|
+
describe 'with explicit schema' do
|
183
|
+
before do
|
184
|
+
@db.create_table(:test) do
|
185
|
+
primary_key :id
|
186
|
+
end
|
187
|
+
@schema = @db['SELECT CURRENT_SCHEMA'].first.values.first
|
188
|
+
@second_schema = @schema + "--2"
|
189
|
+
@db.create_table(Sequel.qualify(@second_schema,:test)) do
|
190
|
+
primary_key :id2
|
191
|
+
end
|
192
|
+
end
|
193
|
+
after do
|
194
|
+
@db.drop_table?(Sequel.qualify(@second_schema,:test))
|
195
|
+
@db.drop_table?(:test)
|
196
|
+
end
|
197
|
+
|
198
|
+
specify 'gets correct primary key' do
|
199
|
+
DB.primary_key(:test, :schema => @second_schema).should == :id2
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe '#tables' do
|
205
|
+
before do
|
206
|
+
@schema = @db['SELECT CURRENT_SCHEMA'].first.values.first
|
207
|
+
@second_schema = @schema + "--2"
|
208
|
+
@db.create_table(:test) do
|
209
|
+
primary_key :id
|
210
|
+
end
|
211
|
+
@db.create_table(Sequel.qualify(@second_schema,:test2)) do
|
212
|
+
primary_key :id
|
213
|
+
end
|
214
|
+
end
|
215
|
+
after do
|
216
|
+
@db.drop_table?(Sequel.qualify(@second_schema,:test2))
|
217
|
+
@db.drop_table?(:test)
|
218
|
+
end
|
219
|
+
specify 'on explicit schema' do
|
220
|
+
tables = @db.tables(:schema => @second_schema)
|
221
|
+
tables.should include(:test2)
|
222
|
+
tables.should_not include(:test)
|
223
|
+
end
|
224
|
+
specify 'qualified' do
|
225
|
+
tables = @db.tables(:qualify => true)
|
226
|
+
tables.should include(Sequel::SQL::QualifiedIdentifier.new(@schema.to_sym, :test))
|
227
|
+
tables.should_not include(:test)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#views' do
|
232
|
+
def drop_things
|
233
|
+
@db.drop_view(Sequel.qualify(@second_schema,:test_view2), :if_exists => true)
|
234
|
+
@db.drop_table?(Sequel.qualify(@second_schema,:test_table))
|
235
|
+
@db.drop_view(:test_view, :if_exists => true)
|
236
|
+
@db.drop_table?(:test_table)
|
237
|
+
end
|
238
|
+
before do
|
239
|
+
@schema = @db['SELECT CURRENT_SCHEMA'].single_value
|
240
|
+
@second_schema = @schema + "--2"
|
241
|
+
drop_things
|
242
|
+
@db.create_table(:test_table){Integer :a}
|
243
|
+
@db.create_view :test_view, @db[:test_table]
|
244
|
+
@db.create_table(Sequel.qualify(@second_schema,:test_table)) do
|
245
|
+
Integer :b
|
246
|
+
end
|
247
|
+
@db.create_view(Sequel.qualify(@second_schema, :test_view2),
|
248
|
+
@db[Sequel.qualify(@second_schema, :test_table)])
|
249
|
+
end
|
250
|
+
after do
|
251
|
+
drop_things
|
252
|
+
end
|
253
|
+
specify 'on explicit schema' do
|
254
|
+
views = @db.views(:schema => @second_schema)
|
255
|
+
views.should include(:test_view2)
|
256
|
+
views.should_not include(:test_view)
|
257
|
+
end
|
258
|
+
specify 'qualified' do
|
259
|
+
views = @db.views(:qualify => true)
|
260
|
+
views.should include(Sequel::SQL::QualifiedIdentifier.new(@schema.to_sym, :test_view))
|
261
|
+
views.should_not include(:test)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe 'prepared statements' do
|
266
|
+
def create_table
|
267
|
+
@db.create_table!(:test) {Integer :a; Text :b}
|
268
|
+
@db[:test].insert(1, 'blueberries')
|
269
|
+
@db[:test].insert(2, 'trucks')
|
270
|
+
@db[:test].insert(3, 'foxes')
|
271
|
+
end
|
272
|
+
def drop_table
|
273
|
+
@db.drop_table?(:test)
|
274
|
+
end
|
275
|
+
before do
|
276
|
+
create_table
|
277
|
+
end
|
278
|
+
after do
|
279
|
+
drop_table
|
280
|
+
end
|
281
|
+
|
282
|
+
it 're-prepares on stale statement' do
|
283
|
+
@db[:test].filter(:a=>:$n).prepare(:all, :select_a).call(:n=>2).to_a.should == [{:a => 2, :b => 'trucks'}]
|
284
|
+
drop_table
|
285
|
+
create_table
|
286
|
+
@db[:test].filter(:a=>:$n).prepare(:all, :select_a).call(:n=>2).to_a.should == [{:a => 2, :b => 'trucks'}]
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'can call already prepared' do
|
290
|
+
@db[:test].filter(:a=>:$n).prepare(:all, :select_a).call(:n=>2).to_a.should == [{:a => 2, :b => 'trucks'}]
|
291
|
+
drop_table
|
292
|
+
create_table
|
293
|
+
@db.call(:select_a, :n=>2).to_a.should == [{:a => 2, :b => 'trucks'}]
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe 'Database schema modifiers' do
|
298
|
+
# this test was copied from sequel's integration/schema_test because that one drops a serial primary key which is not
|
299
|
+
# currently supported in fdbsql
|
300
|
+
specify "should be able to specify constraint names for column constraints" do
|
301
|
+
@db.create_table!(:items2){Integer :id, :primary_key=>true, :primary_key_constraint_name=>:foo_pk}
|
302
|
+
@db.create_table!(:items){foreign_key :id, :items2, :unique=>true, :foreign_key_constraint_name => :foo_fk, :unique_constraint_name => :foo_uk, :null=>false}
|
303
|
+
@db.alter_table(:items){drop_constraint :foo_fk, :type=>:foreign_key; drop_constraint :foo_uk, :type=>:unique}
|
304
|
+
@db.alter_table(:items2){drop_constraint :foo_pk, :type=>:primary_key}
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
describe 'Dataset' do
|
310
|
+
before(:all) do
|
311
|
+
@db = DB
|
312
|
+
end
|
313
|
+
|
314
|
+
describe 'provides_accurate_rows_matched' do
|
315
|
+
before do
|
316
|
+
DB.create_table!(:test) {Integer :a}
|
317
|
+
DB[:test].insert(1)
|
318
|
+
DB[:test].insert(2)
|
319
|
+
DB[:test].insert(3)
|
320
|
+
DB[:test].insert(4)
|
321
|
+
DB[:test].insert(5)
|
322
|
+
end
|
323
|
+
|
324
|
+
after do
|
325
|
+
DB.drop_table?(:test)
|
326
|
+
end
|
327
|
+
|
328
|
+
specify '#delete' do
|
329
|
+
DB[:test].where(:a => 8..10).delete.should == 0
|
330
|
+
DB[:test].where(:a => 5).delete.should == 1
|
331
|
+
DB[:test].where(:a => 1..3).delete.should == 3
|
332
|
+
end
|
333
|
+
|
334
|
+
specify '#update' do
|
335
|
+
DB[:test].where(:a => 8..10).update(:a => Sequel.+(:a, 10)).should == 0
|
336
|
+
DB[:test].where(:a => 5).update(:a => Sequel.+(:a, 1000)).should == 1
|
337
|
+
DB[:test].where(:a => 1..3).update(:a => Sequel.+(:a, 100)).should == 3
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
341
|
+
|
342
|
+
describe 'intersect and except ALL' do
|
343
|
+
before do
|
344
|
+
DB.create_table!(:test) {Integer :a; Integer :b}
|
345
|
+
DB[:test].insert(1, 10)
|
346
|
+
DB[:test].insert(2, 10)
|
347
|
+
DB[:test].insert(8, 15)
|
348
|
+
DB[:test].insert(2, 10)
|
349
|
+
DB[:test].insert(2, 10)
|
350
|
+
DB[:test].insert(1, 10)
|
351
|
+
|
352
|
+
DB.create_table!(:test2) {Integer :a; Integer :b}
|
353
|
+
DB[:test2].insert(1, 10)
|
354
|
+
DB[:test2].insert(2, 10)
|
355
|
+
DB[:test2].insert(2, 12)
|
356
|
+
DB[:test2].insert(3, 10)
|
357
|
+
DB[:test2].insert(1, 10)
|
358
|
+
end
|
359
|
+
|
360
|
+
after do
|
361
|
+
DB.drop_table?(:test)
|
362
|
+
DB.drop_table?(:test2)
|
363
|
+
end
|
364
|
+
|
365
|
+
specify 'intersect all' do
|
366
|
+
@db[:test].intersect(@db[:test2], :all => true).map{|r| [r[:a],r[:b]]}.to_a.sort.should == [[1, 10], [1,10], [2, 10]]
|
367
|
+
end
|
368
|
+
|
369
|
+
specify 'except all' do
|
370
|
+
@db[:test].except(@db[:test2], :all => true).map{|r| [r[:a],r[:b]]}.to_a.sort.should == [[2,10], [2, 10], [8,15]]
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
describe 'is' do
|
375
|
+
before do
|
376
|
+
DB.create_table!(:test) {Integer :a; Boolean :b}
|
377
|
+
DB[:test].insert(1, nil)
|
378
|
+
DB[:test].insert(2, true)
|
379
|
+
DB[:test].insert(3, false)
|
380
|
+
end
|
381
|
+
after do
|
382
|
+
DB.drop_table?(:test)
|
383
|
+
end
|
384
|
+
|
385
|
+
specify 'true' do
|
386
|
+
DB[:test].select(:a).where(Sequel::SQL::ComplexExpression.new(:IS, :b, true)).map{|r| r[:a]}.should == [2]
|
387
|
+
end
|
388
|
+
|
389
|
+
specify 'not true' do
|
390
|
+
DB[:test].select(:a).where(Sequel::SQL::ComplexExpression.new(:'IS NOT', :b, true)).map{|r| r[:a]}.should == [1, 3]
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
describe 'insert empty values' do
|
395
|
+
before do
|
396
|
+
DB.create_table!(:test) {primary_key :a}
|
397
|
+
end
|
398
|
+
after do
|
399
|
+
DB.drop_table?(:test)
|
400
|
+
end
|
401
|
+
|
402
|
+
specify 'inserts defaults and returns pk' do
|
403
|
+
DB[:test].insert().should == 1 # 1 should be the pk
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
describe 'function names' do
|
408
|
+
before do
|
409
|
+
DB.create_table!(:test) {Text :a; Text :b}
|
410
|
+
DB[:test].insert('1', '')
|
411
|
+
DB[:test].insert('2', 'trucks')
|
412
|
+
DB[:test].insert('3', 'foxes')
|
413
|
+
end
|
414
|
+
after do
|
415
|
+
DB.drop_table?(:test)
|
416
|
+
end
|
417
|
+
|
418
|
+
specify 'evaluate' do
|
419
|
+
DB[:test].select(Sequel.function(:now)).count == 1
|
420
|
+
DB[:test].select(Sequel.as(Sequel.function(:concat, :a, :b), :c)).map{|r| r[:c]}.should == ['1','2trucks','3foxes']
|
421
|
+
end
|
422
|
+
|
423
|
+
specify 'get quoted' do
|
424
|
+
DB[:test].select(Sequel.function(:now).quoted).sql.should =~ /"now"\(\)/
|
425
|
+
DB[:test].select(Sequel.as(Sequel.function(:concat, :a, :b).quoted, :c)).sql.should =~ /"concat"\("a", "b"\)/
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|