jdbc-helper 0.1.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.
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+ # Junegunn Choi (junegunn.c@gmail.com)
3
+
4
+ module JDBCHelper
5
+ # Shortcut connector for Oracle
6
+ module OracleConnector
7
+ include Constants
8
+ include Constants::Connector
9
+
10
+ def self.connect(host, user, password, service_name, timeout = DEFAULT_LOGIN_TIMEOUT)
11
+ Connection.new(
12
+ :driver => JDBC_DRIVER[:oracle],
13
+ :url => "jdbc:oracle:thin:@#{host}/#{service_name}",
14
+ :user => user,
15
+ :password => password,
16
+ :timeout => timeout)
17
+ end
18
+
19
+ def self.connect_by_sid(host, user, password, sid, timeout = DEFAULT_LOGIN_TIMEOUT)
20
+ Connection.new(
21
+ :driver => JDBC_DRIVER[:oracle],
22
+ :url => "jdbc:oracle:thin:@#{host}:#{sid}",
23
+ :user => user,
24
+ :password => password,
25
+ :timeout => timeout)
26
+ end
27
+ end#OracleConnector
28
+ end#JDBCHelper
29
+
@@ -0,0 +1,26 @@
1
+ # encoding: UTF-8
2
+ # Junegunn Choi (junegunn.c@gmail.com)
3
+
4
+ module JDBCHelper
5
+ module Constants
6
+ # Default login timeout is set to 60 seconds
7
+ DEFAULT_LOGIN_TIMEOUT = 60
8
+
9
+ # Constants only for Connectors
10
+ module Connector
11
+ JDBC_DRIVER = {
12
+ :oracle => 'oracle.jdbc.driver.OracleDriver',
13
+ :mysql => 'com.mysql.jdbc.Driver'
14
+ }
15
+
16
+ DEFAULT_PARAMETERS = {
17
+ :mysql => {
18
+ 'zeroDateTimeBehavior' => 'convertToNull',
19
+ 'rewriteBatchedStatements' => 'true',
20
+ 'useServerPrepStmts' => 'true',
21
+ 'useCursorFetch' => 'true'
22
+ }
23
+ }
24
+ end#Connector
25
+ end#Constants
26
+ end#JDBCHelper
data/test/database.yml ADDED
@@ -0,0 +1,13 @@
1
+ ---
2
+ mysql:
3
+ driver: com.mysql.jdbc.Driver
4
+ url: jdbc:mysql://localhost/test
5
+ user: mysql
6
+ password:
7
+
8
+ # oracle:
9
+ # driver: com.mysql.jdbc.Driver
10
+ # url: jdbc:mysql://localhost/test
11
+ # user: mysql
12
+ # password:
13
+
data/test/helper.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ require 'jdbc-helper'
15
+
16
+ class Test::Unit::TestCase
17
+ end
@@ -0,0 +1,292 @@
1
+ require 'helper'
2
+
3
+ class TestJdbcHelper < Test::Unit::TestCase
4
+ def setup
5
+ require 'yaml'
6
+ @config = YAML.load File.read(File.dirname(__FILE__) + '/database.yml')
7
+ end
8
+
9
+ def teardown
10
+
11
+ end
12
+
13
+ TEST_TABLE = 'tmp_jdbc_helper_test'
14
+
15
+ def each_connection
16
+ @config.each do | db, conn_info |
17
+ conn = JDBCHelper::Connection.new(conn_info)
18
+ begin
19
+ yield conn
20
+ ensure
21
+ conn.close
22
+ end
23
+ end
24
+ end
25
+
26
+ def get_one_two
27
+ "
28
+ select 1 one, 'two' two from dual
29
+ union all
30
+ select 1 one, 'two' two from dual
31
+ "
32
+ end
33
+
34
+ def check_one_two(rec)
35
+ assert_equal 2, rec.length
36
+
37
+ assert_equal 1, rec.one
38
+ assert_equal 1, rec[0]
39
+ assert_equal 1, rec['one']
40
+
41
+ assert_equal 'two', rec.two
42
+ assert_equal 'two', rec[1]
43
+ assert_equal 'two', rec['two']
44
+
45
+ assert_raise(NameError) { rec.three }
46
+ assert_raise(NameError) { rec['three'] }
47
+ assert_raise(RangeError) { rec[3] }
48
+ end
49
+
50
+ def reset_test_table conn
51
+ conn.update "drop table #{TEST_TABLE}" rescue nil
52
+ cnt = conn.update '
53
+ create table tmp_jdbc_helper_test (
54
+ a int primary key,
55
+ b varchar(100)
56
+ )'
57
+ assert_equal 0, cnt
58
+ end
59
+
60
+ # ---------------------------------------------------------------
61
+
62
+ def test_connect_and_close
63
+ @config.each do | db, conn_info |
64
+ 4.times do | i |
65
+ # With or without timeout parameter
66
+ conn_info['timeout'] = 60 if i % 2 == 1
67
+
68
+ # Can connect with hash with symbol keys?
69
+ conn_info.keys.each do | str_key |
70
+ conn_info[str_key.to_sym] = conn_info.delete str_key
71
+ end if i % 2 == 0
72
+
73
+ conn = JDBCHelper::Connection.new(conn_info)
74
+ assert_equal(conn.closed?, false)
75
+ conn.close
76
+ assert_equal(conn.closed?, true)
77
+ [ :query, :update, :add_batch, :prepare ].each do | met |
78
+ assert_raise(RuntimeError) { conn.send met, "A" }
79
+ end
80
+ [ :execute_batch, :clear_batch ].each do | met |
81
+ assert_raise(RuntimeError) { conn.send met }
82
+ end
83
+
84
+ # initialize with execution block
85
+ conn = JDBCHelper::Connection.new(conn_info) do | c |
86
+ c.query('select 1 from dual')
87
+ assert_equal c.closed?, false
88
+ end
89
+ assert conn.closed?
90
+ end
91
+ end
92
+ end
93
+
94
+ def test_query_enumerate
95
+ each_connection do | conn |
96
+ # Query without a block => Array
97
+ query_result = conn.query get_one_two
98
+ assert query_result.is_a? Array
99
+ assert_equal 2, query_result.length
100
+ check_one_two(query_result.first)
101
+
102
+ # Query with a block
103
+ count = 0
104
+ conn.query(get_one_two) do | row |
105
+ check_one_two row
106
+ count += 1
107
+ end
108
+ assert_equal 2, count
109
+
110
+ # Enumerate
111
+ enum = conn.enumerate(get_one_two)
112
+ assert enum.is_a? Enumerable
113
+ assert enum.closed? == false
114
+ a = enum.to_a
115
+ assert_equal 2, a.length
116
+ check_one_two a.first
117
+ assert enum.closed? == true
118
+ end
119
+ end
120
+
121
+ def test_update_batch
122
+ each_connection do | conn |
123
+ reset_test_table conn
124
+ count = 100
125
+
126
+ iq = lambda do | i |
127
+ "insert into #{TEST_TABLE} values (#{i}, 'A')"
128
+ end
129
+
130
+ # update
131
+ assert_equal 1, conn.update(iq.call 0)
132
+ assert_equal 1, conn.prev_stat.success_count
133
+
134
+ # add_batch execute_batch
135
+ reset_test_table conn
136
+
137
+ count.times do | p |
138
+ conn.add_batch iq.call(p)
139
+ end
140
+ conn.execute_batch
141
+ assert_equal count, conn.query("select count(*) from #{TEST_TABLE}")[0][0]
142
+
143
+ # add_batch clear_batch
144
+ reset_test_table conn
145
+
146
+ count.times do | p |
147
+ conn.add_batch iq.call(p)
148
+ end
149
+ conn.clear_batch
150
+ assert_equal 0, conn.query("select count(*) from #{TEST_TABLE}")[0][0]
151
+ end
152
+ end
153
+
154
+ def test_prepared_query_enumerate
155
+ each_connection do | conn |
156
+ sel = conn.prepare get_one_two
157
+ assert sel.closed? == false
158
+
159
+ # Query without a block => Array
160
+ query_result = sel.query
161
+ assert query_result.is_a? Array
162
+ assert_equal 2, query_result.length
163
+ check_one_two(query_result.first)
164
+
165
+ # Query with a block
166
+ count = 0
167
+ sel.query do | row |
168
+ check_one_two row
169
+ count += 1
170
+ end
171
+ assert_equal 2, count
172
+
173
+ # Enumerate
174
+ enum = sel.enumerate
175
+ assert enum.is_a? Enumerable
176
+ assert enum.closed? == false
177
+ a = enum.to_a
178
+ assert_equal 2, a.length
179
+ check_one_two a.first
180
+ assert enum.closed? == true
181
+
182
+ sel.close
183
+ assert sel.closed?
184
+ [ :query, :update, :add_batch, :execute_batch, :clear_batch ].each do | met |
185
+ assert_raise(RuntimeError) { sel.send met }
186
+ end
187
+ end
188
+ end
189
+
190
+ def test_prepared_update_batch
191
+ each_connection do | conn |
192
+ reset_test_table conn
193
+ ins = conn.prepare "insert into #{TEST_TABLE} values (?, ?)"
194
+ count = 100
195
+
196
+ # update
197
+ assert ins.closed? == false
198
+ assert_equal 1, ins.update(0, 'A')
199
+ assert_equal 1, conn.prev_stat.success_count
200
+ ins.close
201
+
202
+ # add_batch execute_batch
203
+ reset_test_table conn
204
+ ins = conn.prepare "insert into #{TEST_TABLE} values (?, ?)"
205
+
206
+ count.times do | p |
207
+ ins.add_batch(p + 1, 'A')
208
+ end
209
+ ins.execute_batch
210
+ assert_equal count, conn.query("select count(*) from #{TEST_TABLE}")[0][0]
211
+ ins.close
212
+
213
+ # add_batch clear_batch
214
+ reset_test_table conn
215
+ ins = conn.prepare "insert into #{TEST_TABLE} values (?, ?)"
216
+
217
+ count.times do | p |
218
+ ins.add_batch(p + 1, 'A')
219
+ end
220
+ ins.clear_batch
221
+ assert_equal 0, conn.query("select count(*) from #{TEST_TABLE}")[0][0]
222
+
223
+ # close closed?
224
+ assert ins.closed? == false
225
+ ins.close
226
+ assert ins.closed?
227
+ [ :query, :update, :add_batch, :execute_batch, :clear_batch ].each do | met |
228
+ assert_raise(RuntimeError) { ins.send met }
229
+ end
230
+ end
231
+ end
232
+
233
+ def test_transaction
234
+ each_connection do | conn |
235
+ reset_test_table conn
236
+ count = 100
237
+
238
+ 3.times do | i |
239
+ sum = 0
240
+ conn.update "delete from #{TEST_TABLE}"
241
+ conn.transaction do | tx |
242
+ count.times.each_slice(10) do | slice |
243
+ slice.each do | p |
244
+ conn.add_batch("insert into #{TEST_TABLE} values (#{p}, 'xxx')")
245
+ sum += p
246
+ end
247
+ conn.execute_batch
248
+ end
249
+ result = conn.query("select count(*), sum(a) from #{TEST_TABLE}").first
250
+
251
+ assert_equal count, result.first
252
+ assert_equal sum, result.last.to_i
253
+
254
+ case i
255
+ when 0 then tx.rollback
256
+ when 1 then tx.commit
257
+ else
258
+ nil # committed implicitly
259
+ end
260
+
261
+ flunk 'This should not be executed' if i < 2
262
+ end
263
+
264
+ assert_equal (i == 0 ? 0 : count),
265
+ conn.query("select count(*) from #{TEST_TABLE}").first.first
266
+ end
267
+ end
268
+ end
269
+
270
+ def test_connectors
271
+ @config.each do | db, conn_info |
272
+ if db == 'mysql'
273
+ host = conn_info['url'].match(%r{//(.*?)/})[1]
274
+ db = conn_info['url'].match(%r{/([^/?]*?)(\?.*)?$})[1]
275
+ conn = JDBCHelper::MySQLConnector.connect(host, conn_info['user'], conn_info['password'], db)
276
+
277
+ assert conn.closed? == false
278
+ conn.close
279
+ assert conn.closed?
280
+ elsif db == 'oracle'
281
+ host = conn_info['url'].match(%r{//(.*?)/})[1]
282
+ svc = conn_info['url'].match(%r{/([^/?]*?)(\?.*)?$})[1]
283
+ conn = JDBCHelper::OracleConnector.connect(host, conn_info['user'], conn_info['password'], svc)
284
+
285
+ assert conn.closed? == false
286
+ conn.close
287
+ assert conn.closed?
288
+ end
289
+ end
290
+ end
291
+ end
292
+
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jdbc-helper
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.2
6
+ platform: ruby
7
+ authors:
8
+ - Junegunn Choi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-01 00:00:00 +09:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bundler
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 1.0.0
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: jeweler
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 1.5.2
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: rcov
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id003
49
+ description: JDBCHelper::Connection object wraps around a JDBC connection and provides much nicer interface to crucial database operations from primitive selects and updates to more complex ones involving batch updates, prepared statements and transactions.
50
+ email: junegunn.c@gmail.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - LICENSE.txt
57
+ - README.rdoc
58
+ files:
59
+ - lib/jdbc-helper.rb
60
+ - lib/jdbc-helper/connection.rb
61
+ - lib/jdbc-helper/connection/prepared_statement.rb
62
+ - lib/jdbc-helper/connection/result_set_enumerator.rb
63
+ - lib/jdbc-helper/connection/row.rb
64
+ - lib/jdbc-helper/connection/statement_pool.rb
65
+ - lib/jdbc-helper/connector.rb
66
+ - lib/jdbc-helper/connector/mysql_connector.rb
67
+ - lib/jdbc-helper/connector/oracle_connector.rb
68
+ - lib/jdbc-helper/constants.rb
69
+ - LICENSE.txt
70
+ - README.rdoc
71
+ - test/database.yml
72
+ - test/helper.rb
73
+ - test/test_jdbc-helper.rb
74
+ has_rdoc: true
75
+ homepage: http://github.com/junegunn/jdbc-helper
76
+ licenses:
77
+ - MIT
78
+ post_install_message:
79
+ rdoc_options: []
80
+
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.5.1
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: A JDBC helper for Ruby/Database developers
102
+ test_files:
103
+ - test/database.yml
104
+ - test/helper.rb
105
+ - test/test_jdbc-helper.rb