jdbc-helper 0.7.1 → 0.7.2
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/README.markdown
CHANGED
@@ -112,6 +112,16 @@ end
|
|
112
112
|
del_count = conn.update("DELETE FROM T")
|
113
113
|
```
|
114
114
|
|
115
|
+
### Executing any SQL
|
116
|
+
```ruby
|
117
|
+
rset = conn.execute("SELECT * FROM T")
|
118
|
+
rset.each do |row|
|
119
|
+
# Returned result must be used or closed
|
120
|
+
end
|
121
|
+
|
122
|
+
del_count = conn.execute("DELETE FROM T")
|
123
|
+
```
|
124
|
+
|
115
125
|
### Transaction
|
116
126
|
```ruby
|
117
127
|
committed = conn.transaction do |tx|
|
@@ -24,7 +24,7 @@ class ParameterizedStatement
|
|
24
24
|
def set_param(idx, param)
|
25
25
|
case param
|
26
26
|
when NilClass
|
27
|
-
|
27
|
+
set_null idx, param
|
28
28
|
when Fixnum
|
29
29
|
@java_obj.setLong idx, param
|
30
30
|
when Bignum
|
@@ -64,6 +64,10 @@ class ParameterizedStatement
|
|
64
64
|
end
|
65
65
|
|
66
66
|
private
|
67
|
+
def set_null idx, param
|
68
|
+
@java_obj.setNull idx, java.sql.Types::NULL
|
69
|
+
end
|
70
|
+
|
67
71
|
def measure_exec(type, &blk) # :nodoc:
|
68
72
|
@conn.send(:measure_exec, type, &blk)
|
69
73
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# Junegunn Choi (junegunn.c@gmail.com)
|
3
3
|
|
4
|
+
require 'logger'
|
5
|
+
|
4
6
|
module JDBCHelper
|
5
7
|
class Connection
|
6
8
|
# An encapsulation of Java PreparedStatment object.
|
@@ -15,8 +17,7 @@ class PreparedStatement < ParameterizedStatement
|
|
15
17
|
# Returns the number of parameters required
|
16
18
|
# @return [Fixnum]
|
17
19
|
def parameter_count
|
18
|
-
@pmd
|
19
|
-
@pmd.get_parameter_count
|
20
|
+
@pmd.getParameterCount
|
20
21
|
end
|
21
22
|
|
22
23
|
# @return [NilClass]
|
@@ -26,6 +27,18 @@ class PreparedStatement < ParameterizedStatement
|
|
26
27
|
@java_obj = nil
|
27
28
|
end
|
28
29
|
|
30
|
+
# @return [Fixnum|ResultSetEnumerator]
|
31
|
+
def execute(*params)
|
32
|
+
check_closed
|
33
|
+
|
34
|
+
set_params(params)
|
35
|
+
if measure_exec(:p_execute) { @java_obj.execute }
|
36
|
+
ResultSetEnumerator.new(measure_exec(:p_query) { @java_obj.getResultSet })
|
37
|
+
else
|
38
|
+
@java_obj.getUpdateCount
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
29
42
|
# @return [Fixnum]
|
30
43
|
def update(*params)
|
31
44
|
check_closed
|
@@ -99,8 +112,23 @@ private
|
|
99
112
|
end
|
100
113
|
end
|
101
114
|
|
115
|
+
def set_null idx, param
|
116
|
+
@java_obj.setNull idx, @types ? @types[idx - 1] : java.sql.Types::NULL
|
117
|
+
end
|
118
|
+
|
102
119
|
def initialize(*args)
|
103
120
|
super(*args)
|
121
|
+
|
122
|
+
begin
|
123
|
+
@pmd = @java_obj.getParameterMetaData
|
124
|
+
@types = @pmd.getParameterCount.times.map { |idx|
|
125
|
+
# Oracle does not support getParameterType
|
126
|
+
@pmd.getParameterType(idx + 1) rescue java.sql.Types::NULL
|
127
|
+
}
|
128
|
+
rescue Exception => e
|
129
|
+
Logger.new($stderr).warn e.to_s
|
130
|
+
@types = nil
|
131
|
+
end
|
104
132
|
end
|
105
133
|
end#PreparedStatment
|
106
134
|
end#Connection
|
@@ -252,6 +252,29 @@ class Connection
|
|
252
252
|
status == :committed
|
253
253
|
end
|
254
254
|
|
255
|
+
# Executes an SQL and returns the count of the update rows or a ResultSetEnumerator object
|
256
|
+
# depending on the type of the given statement.
|
257
|
+
# If a ResultSetEnumerator is returned, it must be enumerated or closed.
|
258
|
+
# @param [String] qstr SQL string
|
259
|
+
# @return [Fixnum|ResultSetEnumerator]
|
260
|
+
def execute(qstr)
|
261
|
+
check_closed
|
262
|
+
|
263
|
+
stmt = @spool.take
|
264
|
+
begin
|
265
|
+
if measure_exec(:execute) { stmt.execute(qstr) }
|
266
|
+
ResultSetEnumerator.send(:new, stmt.getResultSet) { @spool.give stmt }
|
267
|
+
else
|
268
|
+
rset = stmt.getUpdateCount
|
269
|
+
@spool.give stmt
|
270
|
+
rset
|
271
|
+
end
|
272
|
+
rescue Exception => e
|
273
|
+
@spool.give stmt
|
274
|
+
raise
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
255
278
|
# Executes an update and returns the count of the updated rows.
|
256
279
|
# @param [String] qstr SQL string
|
257
280
|
# @return [Fixnum] Count of affected records
|
@@ -283,8 +306,8 @@ class Connection
|
|
283
306
|
check_closed
|
284
307
|
|
285
308
|
@spool.with do | stmt |
|
286
|
-
measure_exec(:query) { stmt.
|
287
|
-
process_and_close_rset(
|
309
|
+
rset = measure_exec(:query) { stmt.execute_query(qstr) }
|
310
|
+
process_and_close_rset(rset, &blk)
|
288
311
|
end
|
289
312
|
end
|
290
313
|
|
@@ -309,13 +332,12 @@ class Connection
|
|
309
332
|
|
310
333
|
stmt = @spool.take
|
311
334
|
begin
|
312
|
-
measure_exec(:query) { stmt.
|
335
|
+
rset = measure_exec(:query) { stmt.execute_query(qstr) }
|
336
|
+
return ResultSetEnumerator.send(:new, rset) { @spool.give stmt }
|
313
337
|
rescue Exception
|
314
338
|
@spool.give stmt
|
315
339
|
raise
|
316
340
|
end
|
317
|
-
|
318
|
-
ResultSetEnumerator.send(:new, stmt.get_result_set) { @spool.give stmt }
|
319
341
|
end
|
320
342
|
|
321
343
|
# Adds a statement to be executed in batch
|
data/test/test_connection.rb
CHANGED
@@ -572,5 +572,102 @@ class TestConnection < Test::Unit::TestCase
|
|
572
572
|
end
|
573
573
|
end
|
574
574
|
end
|
575
|
+
|
576
|
+
def test_invalid_sql
|
577
|
+
each_connection do | conn |
|
578
|
+
reset_test_table conn
|
579
|
+
assert_raise(NativeException) do
|
580
|
+
conn.query("delete from #{TEST_TABLE}")
|
581
|
+
end
|
582
|
+
omit "Oracle does not throw Exception when " +
|
583
|
+
"select statement given to executeUpdate" if conn.driver =~ /oracle/
|
584
|
+
assert_raise(NativeException) do
|
585
|
+
conn.update("select * from #{TEST_TABLE}")
|
586
|
+
end
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
def test_execute
|
591
|
+
each_connection do | conn |
|
592
|
+
reset_test_table conn
|
593
|
+
|
594
|
+
rse_class = JDBCHelper::Connection::ResultSetEnumerator
|
595
|
+
|
596
|
+
# Connection#execute
|
597
|
+
assert_equal 1, conn.execute("insert into #{TEST_TABLE} values (0, 'A')")
|
598
|
+
assert_equal 1, conn.execute("insert into #{TEST_TABLE} values (1, 'A')")
|
599
|
+
assert_equal rse_class, (ret = conn.execute("select * from #{TEST_TABLE}")).class
|
600
|
+
cnt = 0
|
601
|
+
ret.each do |row|
|
602
|
+
assert_equal 'A', row.b
|
603
|
+
cnt += 1
|
604
|
+
end
|
605
|
+
assert_equal 2, cnt
|
606
|
+
assert_equal 2, conn.execute("delete from #{TEST_TABLE}")
|
607
|
+
|
608
|
+
# PreparedStatment#execute
|
609
|
+
begin
|
610
|
+
pstmt_ins = conn.prepare "insert into #{TEST_TABLE} values (?, 'A')"
|
611
|
+
pstmt_sel = conn.prepare "select * from #{TEST_TABLE}"
|
612
|
+
pstmt_del = conn.prepare "delete from #{TEST_TABLE}"
|
613
|
+
|
614
|
+
assert_equal 1, pstmt_ins.execute(0)
|
615
|
+
assert_equal 1, pstmt_ins.execute(1)
|
616
|
+
assert_equal rse_class, (ret = pstmt_sel.execute).class
|
617
|
+
cnt = 0
|
618
|
+
ret.each do |row|
|
619
|
+
assert_equal 'A', row.b
|
620
|
+
cnt += 1
|
621
|
+
end
|
622
|
+
assert_equal 2, cnt
|
623
|
+
assert_equal 2, pstmt_del.execute
|
624
|
+
assert_equal rse_class, (ret = pstmt_sel.execute).class
|
625
|
+
ensure
|
626
|
+
[pstmt_ins, pstmt_sel, pstmt_del].each do |ps|
|
627
|
+
ps.close rescue nil
|
628
|
+
end
|
629
|
+
end
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
def test_statement_pool_leakage
|
634
|
+
q = "select * from #{TEST_TABLE}"
|
635
|
+
u = "update #{TEST_TABLE} set a = 1"
|
636
|
+
each_connection do |conn|
|
637
|
+
reset_test_table conn
|
638
|
+
conn.update "insert into #{TEST_TABLE} values (0, 'A')"
|
639
|
+
|
640
|
+
assert_equal 20, 20.times.select {
|
641
|
+
conn.execute(q).close
|
642
|
+
conn.enumerate(q).close
|
643
|
+
conn.query q
|
644
|
+
conn.update u
|
645
|
+
|
646
|
+
conn.execute(q).count == 1
|
647
|
+
}.count
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
def test_prepared_statement_set_null
|
652
|
+
each_connection do |conn|
|
653
|
+
conn.update "drop table #{TEST_TABLE}" rescue nil
|
654
|
+
|
655
|
+
begin
|
656
|
+
conn.update(
|
657
|
+
case conn.driver
|
658
|
+
when /sqlserver/
|
659
|
+
"create table #{TEST_TABLE} (a int, b varchar(100), c datetime2, d decimal(10, 2))"
|
660
|
+
else
|
661
|
+
"create table #{TEST_TABLE} (a int, b varchar(100), c timestamp, d decimal(10, 2))"
|
662
|
+
end
|
663
|
+
)
|
664
|
+
pstmt = conn.prepare "insert into #{TEST_TABLE} (a, b, c, d) values (?, ?, ?, ?)"
|
665
|
+
pstmt.update nil, nil, nil, nil
|
666
|
+
ensure
|
667
|
+
pstmt.close rescue nil
|
668
|
+
conn.update "drop table #{TEST_TABLE}"
|
669
|
+
end
|
670
|
+
end
|
671
|
+
end
|
575
672
|
end
|
576
673
|
|
data/test/testrb
ADDED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: jdbc-helper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.7.
|
5
|
+
version: 0.7.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Junegunn Choi
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-03-13 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: insensitive_hash
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- test/test_connectors.rb
|
111
111
|
- test/test_object_wrapper.rb
|
112
112
|
- test/test_sql.rb
|
113
|
+
- test/testrb
|
113
114
|
homepage: http://github.com/junegunn/jdbc-helper
|
114
115
|
licenses:
|
115
116
|
- MIT
|
@@ -149,3 +150,4 @@ test_files:
|
|
149
150
|
- test/test_connectors.rb
|
150
151
|
- test/test_object_wrapper.rb
|
151
152
|
- test/test_sql.rb
|
153
|
+
- test/testrb
|