jdbc-helper 0.7.7 → 0.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.
- data/{CHANGELOG.markdown → CHANGELOG.md} +14 -0
- data/{README.markdown → README.md} +82 -92
- data/jdbc-helper.gemspec +1 -0
- data/lib/jdbc-helper/connection/prepared_statement.rb +11 -14
- data/lib/jdbc-helper/connection/{result_set_enumerator.rb → result_set.rb} +39 -42
- data/lib/jdbc-helper/connection.rb +23 -59
- data/lib/jdbc-helper/connector/mariadb.rb +24 -0
- data/lib/jdbc-helper/connector/sqlite.rb +19 -0
- data/lib/jdbc-helper/connector.rb +2 -0
- data/lib/jdbc-helper/constants.rb +6 -0
- data/lib/jdbc-helper/sql/expression.rb +21 -79
- data/lib/jdbc-helper/sql/sql.rb +30 -91
- data/lib/jdbc-helper/sql/sql_prepared.rb +31 -122
- data/lib/jdbc-helper/version.rb +1 -1
- data/lib/jdbc-helper/wrapper/function_wrapper.rb +1 -1
- data/lib/jdbc-helper/wrapper/sequence_wrapper.rb +2 -2
- data/lib/jdbc-helper/wrapper/table_wrapper.rb +68 -43
- data/lib/jdbc-helper.rb +1 -0
- data/test/helper.rb +1 -1
- data/test/test_connection.rb +70 -15
- data/test/test_object_wrapper.rb +22 -9
- data/test/test_object_wrapper_0.7.rb +737 -0
- data/test/test_sql.rb +50 -53
- metadata +43 -31
@@ -0,0 +1,737 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestObjectWrapper_0_7 < Test::Unit::TestCase
|
4
|
+
include JDBCHelperTestHelper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@table_name = "tmp_jdbc_helper"
|
8
|
+
@procedure_name = "tmp_jdbc_helper_test_proc"
|
9
|
+
@blob = 'X' * 1024 # * 1024 # FIXME
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
each_connection do |conn|
|
14
|
+
drop_table conn
|
15
|
+
conn.update "drop procedure #{@procedure_name}" rescue nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def blob_data
|
20
|
+
case @type
|
21
|
+
when :postgres
|
22
|
+
@blob
|
23
|
+
else
|
24
|
+
java.io.ByteArrayInputStream.new( @blob.to_java_bytes )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_blob_data is
|
29
|
+
case is
|
30
|
+
when String
|
31
|
+
is
|
32
|
+
when java.io.InputStream
|
33
|
+
br = java.io.BufferedReader.new( java.io.InputStreamReader.new(is, "UTF-8") )
|
34
|
+
output = StringIO.new
|
35
|
+
|
36
|
+
while line = br.readLine
|
37
|
+
output << line
|
38
|
+
end
|
39
|
+
|
40
|
+
output.string
|
41
|
+
else
|
42
|
+
# Blob
|
43
|
+
is.getBytes(1, is.length()).to_a.pack('U*')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_table conn
|
48
|
+
drop_table conn
|
49
|
+
ddl = "
|
50
|
+
create table #{@table_name} (
|
51
|
+
id int primary key,
|
52
|
+
alpha int,
|
53
|
+
beta float,
|
54
|
+
gamma varchar(100),
|
55
|
+
delta #{
|
56
|
+
case @type
|
57
|
+
when :postgres
|
58
|
+
'bytea'
|
59
|
+
when :mysql
|
60
|
+
'longblob'
|
61
|
+
when :sqlserver
|
62
|
+
'varbinary(max)'
|
63
|
+
else
|
64
|
+
'blob'
|
65
|
+
end},
|
66
|
+
num_f decimal(15, 5),
|
67
|
+
num_fstr decimal(30, 10),
|
68
|
+
num_int decimal(9, 0),
|
69
|
+
num_long decimal(18, 0),
|
70
|
+
num_str decimal(30, 0)
|
71
|
+
#{", num_wtf number" if @type == :oracle}
|
72
|
+
)
|
73
|
+
"
|
74
|
+
ddl.gsub('decimal', 'number') if @type == :oracle
|
75
|
+
conn.update ddl
|
76
|
+
end
|
77
|
+
|
78
|
+
def drop_table conn
|
79
|
+
begin
|
80
|
+
conn.update "drop table #{@table_name}"
|
81
|
+
return true
|
82
|
+
rescue Exception
|
83
|
+
return false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_wrapper
|
88
|
+
each_connection do |conn|
|
89
|
+
# With symbol
|
90
|
+
assert_kind_of JDBCHelper::ObjectWrapper, conn.table(:some_table)
|
91
|
+
assert_instance_of JDBCHelper::TableWrapper, conn.table(:some_table)
|
92
|
+
assert_instance_of JDBCHelper::TableWrapper, conn[:some_table]
|
93
|
+
assert_kind_of JDBCHelper::ObjectWrapper, conn.function(:some_func)
|
94
|
+
assert_instance_of JDBCHelper::FunctionWrapper, conn.function(:some_func)
|
95
|
+
assert_kind_of JDBCHelper::ObjectWrapper, conn.procedure(:some_proc)
|
96
|
+
assert_instance_of JDBCHelper::ProcedureWrapper, conn.procedure(:some_proc)
|
97
|
+
assert_equal 'some_table', conn.table(:some_table).name
|
98
|
+
|
99
|
+
# With string
|
100
|
+
assert_kind_of JDBCHelper::ObjectWrapper, conn.table('table')
|
101
|
+
assert_instance_of JDBCHelper::TableWrapper, conn.table('db.table')
|
102
|
+
assert_kind_of JDBCHelper::ObjectWrapper, conn.function('db.some_func')
|
103
|
+
assert_instance_of JDBCHelper::FunctionWrapper, conn.function('some_func')
|
104
|
+
assert_kind_of JDBCHelper::ObjectWrapper, conn.procedure('some_proc')
|
105
|
+
assert_instance_of JDBCHelper::ProcedureWrapper, conn.procedure('db.some_proc')
|
106
|
+
assert_equal 'db.table', conn.table('db.table').name
|
107
|
+
|
108
|
+
# Invalid object name
|
109
|
+
[ ' ', 'object;', 'object -- ', "obj'ect",
|
110
|
+
'obj"ect', 'obj`ect', 'obje(t', 'ob)ect' ].each do |inv|
|
111
|
+
assert_raise(ArgumentError) { conn.table(inv) }
|
112
|
+
assert_raise(ArgumentError) { conn.function(inv) }
|
113
|
+
assert_raise(ArgumentError) { conn.table(inv.to_sym) }
|
114
|
+
assert_raise(ArgumentError) { conn.function(inv.to_sym) }
|
115
|
+
end
|
116
|
+
|
117
|
+
# Abstract class
|
118
|
+
assert_raise(NotImplementedError) { JDBCHelper::ObjectWrapper.new(conn, 'table') }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def insert_params
|
124
|
+
{
|
125
|
+
:alpha => 100,
|
126
|
+
:beta => JDBCHelper::SQL('0.1 + 0.2'),
|
127
|
+
:num_f => 1234567890.12345, # 16 digits
|
128
|
+
:num_fstr => BigDecimal.new("12345678901234567890.12345"),
|
129
|
+
:num_int => 123456789,
|
130
|
+
:num_long => 123456789012345678,
|
131
|
+
:num_str => 123456789012345678901234567890,
|
132
|
+
:num_wtf => 12345.6789
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
def insert table, cnt = 100, offset = 1
|
137
|
+
require 'java'
|
138
|
+
|
139
|
+
params = insert_params.dup
|
140
|
+
params.delete(:num_wtf) unless @type == :oracle
|
141
|
+
|
142
|
+
cnt.times do |pk|
|
143
|
+
icnt = table.
|
144
|
+
default(:gamma => 'hello world').
|
145
|
+
default(:alpha => 200).
|
146
|
+
insert(params.merge(
|
147
|
+
:id => pk + offset,
|
148
|
+
:delta => blob_data)
|
149
|
+
)
|
150
|
+
assert_equal 1, icnt unless table.batch?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_empty
|
155
|
+
each_connection do |conn|
|
156
|
+
create_table conn
|
157
|
+
table = conn.table(@table_name)
|
158
|
+
|
159
|
+
assert table.empty?
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_function_wrapper
|
164
|
+
each_connection do |conn|
|
165
|
+
# SQL Server does not have mod function
|
166
|
+
assert_equal 2.to_i, conn.function(:mod).call(5, 3).to_i unless @type == :sqlserver
|
167
|
+
assert_equal 'yeah', get_blob_data( conn.function(:coalesce).call(nil, nil, 'yeah', 'no') )
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_procedure_wrapper
|
172
|
+
each_connection do |conn, conn_info|
|
173
|
+
next unless [:mysql, :oracle].include?(@type) # TODO: postgres / sqlserver
|
174
|
+
|
175
|
+
{
|
176
|
+
:proc => @procedure_name,
|
177
|
+
:db_proc => [conn_info['database'], @procedure_name].join('.')
|
178
|
+
}.each do |mode, prname|
|
179
|
+
create_test_procedure_simple conn, prname
|
180
|
+
|
181
|
+
pr = conn.procedure(prname)
|
182
|
+
pr.call # should be ok without any arguments
|
183
|
+
|
184
|
+
# Complex case
|
185
|
+
create_test_procedure conn, prname
|
186
|
+
pr.refresh
|
187
|
+
|
188
|
+
result = pr.call 'hello', 10, [100, Fixnum], [Time.now, Time], nil, Float, String
|
189
|
+
assert_instance_of Hash, result
|
190
|
+
assert_equal 1000, result[3]
|
191
|
+
assert_equal 'hello', result[7]
|
192
|
+
|
193
|
+
result = pr.call(
|
194
|
+
:io1 => [100, Fixnum],
|
195
|
+
'io2' => [Time.now, Time],
|
196
|
+
:i2 => 10,
|
197
|
+
:i1 => 'hello',
|
198
|
+
:o1 => Float, 'o2' => String)
|
199
|
+
assert_instance_of Hash, result
|
200
|
+
assert_equal 1000, result[:io1]
|
201
|
+
assert_equal 'hello', result['o2']
|
202
|
+
|
203
|
+
# Test default values
|
204
|
+
# - MySQL does not support default values
|
205
|
+
# - Oracle JDBC does not fully implement getProcedureColumns
|
206
|
+
# => Cannot get default values with standard interface => Pending
|
207
|
+
if @type != :mysql
|
208
|
+
pend("Not tested") do
|
209
|
+
result = pr.call(
|
210
|
+
:io1 => [100, Fixnum],
|
211
|
+
'io2' => [Time.now, Time],
|
212
|
+
#:i2 => 10,
|
213
|
+
:i1 => 'hello',
|
214
|
+
:o1 => Float, 'o2' => String)
|
215
|
+
assert_instance_of Hash, result
|
216
|
+
assert_equal 100, result[:io1]
|
217
|
+
assert_equal 'hello', result['o2']
|
218
|
+
|
219
|
+
result = pr.call 'hello', [100, Fixnum], [Time.now, Time], nil, Float, String
|
220
|
+
assert_instance_of Hash, result
|
221
|
+
assert_equal 100, result[3]
|
222
|
+
assert_equal 'hello', result[7]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end#prname
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_insert_count
|
230
|
+
each_connection do |conn|
|
231
|
+
create_table conn
|
232
|
+
table = conn.table(@table_name)
|
233
|
+
|
234
|
+
# Count
|
235
|
+
assert_equal 0, table.count
|
236
|
+
assert table.empty?
|
237
|
+
|
238
|
+
# Insert
|
239
|
+
insert table
|
240
|
+
|
241
|
+
# Empty?
|
242
|
+
assert_equal false, table.empty?
|
243
|
+
assert_equal true, table.empty?(:alpha => 999)
|
244
|
+
assert_equal true, table.where(:alpha => 999).empty?
|
245
|
+
|
246
|
+
# Count
|
247
|
+
assert_equal 100, table.count
|
248
|
+
assert_equal 100, table.count(:alpha => 100)
|
249
|
+
assert_equal 1, table.where(:alpha => 100).count(:id => 1) # scoped
|
250
|
+
assert_equal 0, table.where(:alpha => 200).count(:id => 1) # scoped
|
251
|
+
assert_equal 0, table.count(:beta => nil)
|
252
|
+
|
253
|
+
assert_equal 100, table.where(:alpha => 100).count
|
254
|
+
assert_equal 0, table.where(:beta => nil).count
|
255
|
+
assert_equal 40, table.where('id >= 11', 'id <= 50').count
|
256
|
+
assert_equal 40, table.where('id >= 11').count('id <= 50')
|
257
|
+
assert_equal 40, table.where('id >= 11').where('id <= 50').count
|
258
|
+
assert_equal 40, table.where('id >= 11').where('id <= 50').where('1 = 1').count
|
259
|
+
assert_equal 0, table.where(:alpha => 100).count(:beta => nil)
|
260
|
+
|
261
|
+
assert_equal true, table.empty?(:beta => nil)
|
262
|
+
assert_equal true, table.where(:beta => nil).empty?
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_insert_ignore
|
267
|
+
each_connection do |conn|
|
268
|
+
next unless @type == :mysql
|
269
|
+
|
270
|
+
create_table conn
|
271
|
+
table = conn.table(@table_name)
|
272
|
+
params = {
|
273
|
+
:id => 1,
|
274
|
+
:alpha => 100,
|
275
|
+
:beta => JDBCHelper::SQL('0.1 + 0.2'),
|
276
|
+
:gamma => 'hello world' }
|
277
|
+
|
278
|
+
100.times do
|
279
|
+
table.insert_ignore(params)
|
280
|
+
end
|
281
|
+
|
282
|
+
assert_equal 1, table.count
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_replace
|
287
|
+
each_connection do |conn|
|
288
|
+
next unless @type == :mysql
|
289
|
+
|
290
|
+
create_table conn
|
291
|
+
table = conn.table(@table_name)
|
292
|
+
params = {
|
293
|
+
:id => 1,
|
294
|
+
:beta => JDBCHelper::SQL('0.1 + 0.2'),
|
295
|
+
:gamma => 'hello world' }
|
296
|
+
|
297
|
+
100.times do |i|
|
298
|
+
table.replace(params.merge(:alpha => i))
|
299
|
+
end
|
300
|
+
|
301
|
+
assert_equal 1, table.count
|
302
|
+
assert_equal 99, table.select.first.alpha
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_select
|
307
|
+
each_connection do |conn|
|
308
|
+
create_table conn
|
309
|
+
table = conn.table(@table_name)
|
310
|
+
insert table
|
311
|
+
assert_equal 100, table.count
|
312
|
+
|
313
|
+
def check_row row
|
314
|
+
assert_equal 100, row.alpha
|
315
|
+
assert_equal 'hello world', row.gamma
|
316
|
+
end
|
317
|
+
|
318
|
+
cnt = 0
|
319
|
+
table.select do |row|
|
320
|
+
cnt += 1
|
321
|
+
check_row row
|
322
|
+
end
|
323
|
+
assert_equal 100, cnt
|
324
|
+
|
325
|
+
# each
|
326
|
+
cnt = 0
|
327
|
+
table.each do |row|
|
328
|
+
cnt += 1
|
329
|
+
check_row row
|
330
|
+
end
|
331
|
+
assert_equal 100, cnt
|
332
|
+
|
333
|
+
# As Enumerable
|
334
|
+
cnt = 0
|
335
|
+
table.each_slice(10) do |rows|
|
336
|
+
cnt += rows.length
|
337
|
+
end
|
338
|
+
assert_equal 100, cnt
|
339
|
+
|
340
|
+
# Alias
|
341
|
+
cnt = 0
|
342
|
+
table.select('alpha OMega') do |row|
|
343
|
+
cnt += 1
|
344
|
+
assert_equal 100, row.omega
|
345
|
+
assert_equal ['omega'], row.labels.map(&:downcase)
|
346
|
+
end
|
347
|
+
assert_equal 100, cnt
|
348
|
+
|
349
|
+
# Lob, Decimals
|
350
|
+
params = insert_params
|
351
|
+
cols = [:delta, :num_f, :num_fstr, :num_int, :num_long, :num_str]
|
352
|
+
cols << :num_wtf if @type == :oracle
|
353
|
+
table.select(*cols) do |row|
|
354
|
+
blob = row.delta
|
355
|
+
# SQL Server seems to have a bug in getBinaryStream (FIXME)
|
356
|
+
# http://www.herongyang.com/JDBC/SQL-Server-BLOB-getBinaryStream.html
|
357
|
+
assert_equal @blob, get_blob_data(blob) unless @type == :sqlserver
|
358
|
+
assert_equal BigDecimal, row.num_f.class
|
359
|
+
assert_equal BigDecimal, row.num_fstr.class
|
360
|
+
assert_equal Fixnum, row.num_int.class
|
361
|
+
assert_equal Fixnum, row.num_long.class
|
362
|
+
assert_equal Bignum, row.num_str.class
|
363
|
+
assert_equal BigDecimal, row.num_wtf.class if @type == :oracle
|
364
|
+
|
365
|
+
assert_equal params[:num_int], row.num_int
|
366
|
+
assert_equal params[:num_long], row.num_long
|
367
|
+
assert_equal params[:num_str], row.num_str
|
368
|
+
assert_equal params[:num_fstr], row.num_fstr
|
369
|
+
assert_equal params[:num_f], row.num_f
|
370
|
+
assert_equal params[:num_wtf], row.num_wtf if @type == :oracle
|
371
|
+
end
|
372
|
+
|
373
|
+
cnt = 0
|
374
|
+
prev_id = 100
|
375
|
+
table.where(:id => 11..20).order('id desc') do |row|
|
376
|
+
cnt += 1
|
377
|
+
check_row row
|
378
|
+
|
379
|
+
assert row.id.to_i < prev_id
|
380
|
+
prev_id = row.id.to_i
|
381
|
+
end
|
382
|
+
assert_equal 10, cnt
|
383
|
+
|
384
|
+
assert_equal "select a, b, c cc from tmp_jdbc_helper " +
|
385
|
+
"where id between 11 and 20 order by id desc, name asc",
|
386
|
+
table.where(:id => 11..20).
|
387
|
+
select(:a, :b, 'c cc').
|
388
|
+
order('id desc', 'name asc').sql
|
389
|
+
|
390
|
+
assert_equal "select a, b, c cc from tmp_jdbc_helper " +
|
391
|
+
"where (id != 15) and id between 11 and 20 order by id desc, name asc",
|
392
|
+
table.where("id != 15", :id => 11..20).
|
393
|
+
select(:a, :b, 'c cc').
|
394
|
+
order('id desc', 'name asc').sql
|
395
|
+
|
396
|
+
assert_raise(ArgumentError) { table.order }
|
397
|
+
assert_raise(ArgumentError) { table.order.where }
|
398
|
+
assert_raise(ArgumentError) { table.where.order }
|
399
|
+
assert_raise(ArgumentError) { table.select.order }
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
def test_delete
|
404
|
+
each_connection do |conn|
|
405
|
+
create_table conn
|
406
|
+
table = conn.table(@table_name)
|
407
|
+
insert table
|
408
|
+
|
409
|
+
# Count
|
410
|
+
assert_equal 100, table.count
|
411
|
+
|
412
|
+
# Delete
|
413
|
+
assert_equal 10, table.delete(:id => (1...11))
|
414
|
+
assert_equal 10, table.delete(:id => (11..20))
|
415
|
+
assert_equal 1, table.delete(:id => 21)
|
416
|
+
assert_equal 4, table.delete(:id => [22, 23, 24, 25])
|
417
|
+
assert_equal 5, table.delete("id <= 30")
|
418
|
+
assert_equal 10, table.where("id <= 40").delete
|
419
|
+
|
420
|
+
# Could be dangerous (XXX)
|
421
|
+
assert_equal 60, table.delete
|
422
|
+
|
423
|
+
# Count
|
424
|
+
assert_equal 0, table.count
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
def test_update
|
429
|
+
each_connection do |conn|
|
430
|
+
create_table conn
|
431
|
+
table = conn.table(@table_name)
|
432
|
+
insert table
|
433
|
+
|
434
|
+
assert_equal 10, table.update(:beta => 0, :where => { :id => (1..10) })
|
435
|
+
assert_equal 2, table.where(:id => (55..56)).update(:beta => 0, :where => { :id => (51..60) })
|
436
|
+
assert_equal 10, table.where(:id => (11..20)).update(:beta => 1)
|
437
|
+
|
438
|
+
with_default = table.default(:beta => 0)
|
439
|
+
assert_equal 5, with_default.where(:id => (11..15)).update
|
440
|
+
assert_equal 5, with_default.where(:id => (16..20)).update
|
441
|
+
with_default = table.default(:beta => 1)
|
442
|
+
assert_equal 5, with_default.where(:id => (16..20)).update(:beta => 0) # override
|
443
|
+
assert_equal 22, table.count(:beta => 0)
|
444
|
+
assert_equal 100, table.update(:beta => 1)
|
445
|
+
|
446
|
+
# Blob-handling
|
447
|
+
# SQL Server seems to have a bug with binary streams (FIXME)
|
448
|
+
next if @type == :sqlserver
|
449
|
+
|
450
|
+
first_row = table.select(:delta).first
|
451
|
+
blob = first_row.delta
|
452
|
+
|
453
|
+
table.update(:delta => nil)
|
454
|
+
case @type
|
455
|
+
when :postgres
|
456
|
+
table.update(:delta => get_blob_data(blob))
|
457
|
+
else
|
458
|
+
table.update(:delta => blob)
|
459
|
+
end
|
460
|
+
|
461
|
+
table.select('delta') do |row|
|
462
|
+
blob = row.delta
|
463
|
+
assert_equal @blob, get_blob_data(blob)
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
def test_batch
|
469
|
+
each_connection do |conn|
|
470
|
+
# Initialize test table
|
471
|
+
create_table conn
|
472
|
+
table = conn.table(@table_name)
|
473
|
+
insert table
|
474
|
+
|
475
|
+
# Duplicated calls are idempotent
|
476
|
+
btable = table.batch
|
477
|
+
assert_equal btable, btable.batch
|
478
|
+
|
479
|
+
# Batch updates
|
480
|
+
table.batch.delete
|
481
|
+
assert_equal 100, table.count
|
482
|
+
conn.execute_batch
|
483
|
+
assert_equal 0, table.count
|
484
|
+
|
485
|
+
insert table.batch, 50
|
486
|
+
assert_equal 0, table.count
|
487
|
+
table.execute_batch :delete
|
488
|
+
assert_equal 0, table.count
|
489
|
+
table.execute_batch :update
|
490
|
+
assert_equal 0, table.count
|
491
|
+
|
492
|
+
table.batch.delete
|
493
|
+
table.execute_batch :update, :insert
|
494
|
+
assert_equal 50, table.count
|
495
|
+
table.clear_batch
|
496
|
+
|
497
|
+
insert table.batch, 50
|
498
|
+
assert_equal 50, table.count
|
499
|
+
table.clear_batch
|
500
|
+
assert_equal 50, table.count
|
501
|
+
|
502
|
+
table.batch.update(:alpha => JDBCHelper::SQL('alpha * 2'))
|
503
|
+
assert_equal 100, table.select(:alpha).to_a.first.alpha.to_i
|
504
|
+
|
505
|
+
# Independent update inbetween
|
506
|
+
table.delete(:id => 1..10)
|
507
|
+
assert_equal 40, table.count
|
508
|
+
|
509
|
+
# Finally with TableWrapper#execute_batch
|
510
|
+
insert table.batch, 60, 1000
|
511
|
+
assert_equal 40, table.count
|
512
|
+
table.execute_batch :delete, :update
|
513
|
+
assert_equal 40, table.count
|
514
|
+
table.execute_batch :insert
|
515
|
+
assert_equal 100, table.count
|
516
|
+
|
517
|
+
assert_equal 200, table.select(:alpha).to_a.first.alpha.to_i
|
518
|
+
|
519
|
+
# Order of execution
|
520
|
+
table.batch.update(:alpha => JDBCHelper::SQL('alpha * 4'))
|
521
|
+
insert table.batch, 50, 2000
|
522
|
+
table.batch.delete
|
523
|
+
ret = table.execute_batch :delete, :insert, :update
|
524
|
+
omit_if(conn.driver =~ /oracle/) do
|
525
|
+
# https://forums.oracle.com/forums/thread.jspa?threadID=532945
|
526
|
+
assert_equal 100, ret[:delete]
|
527
|
+
assert_equal 50, ret[:insert]
|
528
|
+
assert_equal 50, ret[:update]
|
529
|
+
end
|
530
|
+
assert_equal 50, table.count
|
531
|
+
assert_equal 400, table.select(:alpha).to_a.first.alpha.to_i
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
def test_truncate_table
|
536
|
+
each_connection do |conn|
|
537
|
+
create_table conn
|
538
|
+
table = conn.table(@table_name)
|
539
|
+
insert table
|
540
|
+
|
541
|
+
table.truncate!
|
542
|
+
assert table.empty?
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
def test_drop_table
|
547
|
+
each_connection do |conn|
|
548
|
+
create_table conn
|
549
|
+
table = conn.table(@table_name)
|
550
|
+
table.drop!
|
551
|
+
assert_equal false, drop_table(conn)
|
552
|
+
|
553
|
+
create_table conn
|
554
|
+
table = conn.table(@table_name)
|
555
|
+
table.drop_table! #alias
|
556
|
+
assert_equal false, drop_table(conn)
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
def test_sequence
|
561
|
+
each_connection do |conn|
|
562
|
+
# MySQL and SQL Server doesn't support sequences
|
563
|
+
next if [:mysql, :sqlserver].include?(@type)
|
564
|
+
|
565
|
+
seq = conn.sequence(@table_name + '_seq')
|
566
|
+
seq.reset!(100)
|
567
|
+
assert (prev = seq.nextval) >= 100
|
568
|
+
assert_equal prev, seq.currval
|
569
|
+
assert_equal 1, seq.nextval - prev
|
570
|
+
|
571
|
+
seq.reset! 1, 2
|
572
|
+
assert seq.nextval >= 1
|
573
|
+
assert seq.nextval <= 4
|
574
|
+
assert seq.nextval >= 5
|
575
|
+
|
576
|
+
seq.drop!
|
577
|
+
seq.create!(10)
|
578
|
+
assert seq.nextval >= 10
|
579
|
+
seq.drop!
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
# 0.5.1: Too many open cursors
|
584
|
+
def test_ora_10000
|
585
|
+
each_connection do |conn|
|
586
|
+
create_table conn
|
587
|
+
insert conn.table(@table_name)
|
588
|
+
|
589
|
+
# Batch-enabled object
|
590
|
+
conn.table(@table_name).batch
|
591
|
+
|
592
|
+
10000.times do
|
593
|
+
# Should not fail
|
594
|
+
t = conn.table(@table_name)
|
595
|
+
t.count(:id => 1)
|
596
|
+
|
597
|
+
assert_equal false, t.batch?
|
598
|
+
t2 = t.batch
|
599
|
+
assert_equal false, t.batch?
|
600
|
+
assert_equal true, t2.batch?
|
601
|
+
end
|
602
|
+
|
603
|
+
# OK
|
604
|
+
assert true
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
# Test disabled prepared statements
|
609
|
+
def test_pstmt_disable
|
610
|
+
pend("TODO/TBD") do
|
611
|
+
assert false # FIXME
|
612
|
+
|
613
|
+
each_connection do |conn|
|
614
|
+
create_table conn
|
615
|
+
insert conn.table(@table_name)
|
616
|
+
|
617
|
+
# Batch-enabled object
|
618
|
+
conn.table(@table_name).batch
|
619
|
+
|
620
|
+
10000.times do |i|
|
621
|
+
# Should not fail
|
622
|
+
t = conn.table(@table_name)
|
623
|
+
t.count("id = #{i}")
|
624
|
+
end
|
625
|
+
|
626
|
+
# OK
|
627
|
+
assert true
|
628
|
+
end
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
632
|
+
def test_prepared_statements
|
633
|
+
each_connection do |conn|
|
634
|
+
create_table conn
|
635
|
+
|
636
|
+
# No duplicate preparations
|
637
|
+
t = conn.table(@table_name)
|
638
|
+
t.count(:id => 1)
|
639
|
+
t.count('1 = 0')
|
640
|
+
bt = t.batch
|
641
|
+
|
642
|
+
assert_equal 2, t.prepared_statements[:count].length
|
643
|
+
assert_equal 2, bt.prepared_statements[:count].length
|
644
|
+
|
645
|
+
t.count(:id => 2)
|
646
|
+
t.count('2 = 0')
|
647
|
+
bt.count('3 = 0')
|
648
|
+
assert_equal 4, t.prepared_statements[:count].length
|
649
|
+
assert_equal 4, bt.prepared_statements[:count].length
|
650
|
+
|
651
|
+
t.count(:id => 3)
|
652
|
+
t.batch.count('4 = 0')
|
653
|
+
assert_equal 5, t.prepared_statements[:count].length
|
654
|
+
assert_equal 5, bt.prepared_statements[:count].length
|
655
|
+
assert_equal 5, t.batch.prepared_statements[:count].length
|
656
|
+
assert_equal 5, bt.batch.prepared_statements[:count].length
|
657
|
+
|
658
|
+
t.close
|
659
|
+
assert_equal 0, t.prepared_statements[:count].length
|
660
|
+
assert_equal 0, bt.prepared_statements[:count].length
|
661
|
+
assert_equal 0, t.batch.prepared_statements[:count].length
|
662
|
+
assert_equal 0, bt.batch.prepared_statements[:count].length
|
663
|
+
|
664
|
+
t.batch.batch.batch.count(:id => 1)
|
665
|
+
assert_equal 1, t.prepared_statements[:count].length
|
666
|
+
assert_equal 1, bt.prepared_statements[:count].length
|
667
|
+
assert_equal 1, bt.batch.prepared_statements[:count].length
|
668
|
+
assert_equal 1, t.batch.where('1 = 2').select(:a, :b).prepared_statements[:count].length
|
669
|
+
|
670
|
+
# Should be OK
|
671
|
+
bt.close
|
672
|
+
t.batch.close
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
676
|
+
def test_invalidated_prepared_statements
|
677
|
+
each_connection do |conn|
|
678
|
+
create_table conn
|
679
|
+
|
680
|
+
t = conn.table(@table_name)
|
681
|
+
insert t, 100
|
682
|
+
assert_equal 100, t.count
|
683
|
+
|
684
|
+
create_table conn
|
685
|
+
insert t, 100
|
686
|
+
# SHOULD NOT FAIL
|
687
|
+
assert_equal 100, t.count
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
def test_closed_prepared_statements
|
692
|
+
each_connection do |conn|
|
693
|
+
create_table conn
|
694
|
+
|
695
|
+
t = conn.table(@table_name)
|
696
|
+
insert t, 100
|
697
|
+
assert_equal 100, t.count
|
698
|
+
|
699
|
+
conn.prepared_statements.each { |ps| ps.close }
|
700
|
+
|
701
|
+
# SHOULD NOT FAIL (automatic repreparation)
|
702
|
+
assert_equal 100, t.count
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
706
|
+
def test_closed_prepared_statements_java
|
707
|
+
each_connection do |conn|
|
708
|
+
create_table conn
|
709
|
+
|
710
|
+
t = conn.table(@table_name)
|
711
|
+
insert t, 100
|
712
|
+
assert_equal 100, t.count
|
713
|
+
|
714
|
+
conn.prepared_statements.each { |ps| ps.java_obj.close }
|
715
|
+
|
716
|
+
# SHOULD NOT FAIL (automatic repreparation)
|
717
|
+
assert_equal 100, t.count
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
721
|
+
def test_fetch_size
|
722
|
+
each_connection do |conn|
|
723
|
+
create_table conn
|
724
|
+
|
725
|
+
fsz = 100
|
726
|
+
conn.fetch_size = fsz
|
727
|
+
cnt = cnt2 = 0
|
728
|
+
conn.table(@table_name).fetch_size(fsz) { |row| cnt += 1 }
|
729
|
+
conn.table(@table_name).fetch_size(fsz).each { |row| cnt2 += 1 }
|
730
|
+
assert_equal cnt, conn.table(@table_name).count
|
731
|
+
assert_equal cnt2, conn.table(@table_name).count
|
732
|
+
|
733
|
+
conn.table(@table_name).fetch_size("No").count
|
734
|
+
end
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|