ruby-plsql 0.2.2 → 0.2.3
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/History.txt +8 -0
- data/README.txt +2 -2
- data/lib/plsql/connection.rb +0 -421
- data/lib/plsql/jdbc_connection.rb +302 -0
- data/lib/plsql/oci_connection.rb +165 -0
- data/lib/plsql/procedure.rb +3 -0
- data/lib/ruby_plsql.rb +2 -2
- data/lib/ruby_plsql/version.rb +1 -1
- data/spec/plsql/procedure_spec.rb +102 -3
- data/spec/spec_helper.rb +14 -2
- metadata +15 -24
- data/Manifest.txt +0 -33
- data/Rakefile +0 -4
- data/config/hoe.rb +0 -70
- data/config/requirements.rb +0 -17
- data/log/debug.log +0 -0
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -74
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/rspec.rake +0 -21
- data/tasks/website.rake +0 -17
- data/website/index.html +0 -112
- data/website/index.txt +0 -53
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -138
- data/website/template.rhtml +0 -48
@@ -0,0 +1,302 @@
|
|
1
|
+
module PLSQL
|
2
|
+
class JDBCConnection < Connection
|
3
|
+
def logoff
|
4
|
+
raw_connection.close
|
5
|
+
true
|
6
|
+
rescue
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def commit
|
11
|
+
raw_connection.commit
|
12
|
+
end
|
13
|
+
|
14
|
+
def rollback
|
15
|
+
raw_connection.rollback
|
16
|
+
end
|
17
|
+
|
18
|
+
def autocommit?
|
19
|
+
raw_connection.getAutoCommit
|
20
|
+
end
|
21
|
+
|
22
|
+
def autocommit=(value)
|
23
|
+
raw_connection.setAutoCommit(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def select_first(sql, *bindvars)
|
27
|
+
stmt = prepare_statement(sql, *bindvars)
|
28
|
+
rset = stmt.executeQuery
|
29
|
+
metadata = rset.getMetaData
|
30
|
+
column_count = metadata.getColumnCount
|
31
|
+
if rset.next
|
32
|
+
(1..column_count).map do |i|
|
33
|
+
get_ruby_value_from_result_set(rset,i,metadata.getColumnTypeName(i))
|
34
|
+
end
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
ensure
|
39
|
+
rset.close rescue nil
|
40
|
+
stmt.close rescue nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def select_all(sql, *bindvars, &block)
|
44
|
+
stmt = prepare_statement(sql, *bindvars)
|
45
|
+
results = []
|
46
|
+
row_count = 0
|
47
|
+
rset = stmt.executeQuery
|
48
|
+
metadata = rset.getMetaData
|
49
|
+
column_count = metadata.getColumnCount
|
50
|
+
while rset.next
|
51
|
+
row_with_typecast = (1..column_count).map do |i|
|
52
|
+
get_ruby_value_from_result_set(rset,i,metadata.getColumnTypeName(i))
|
53
|
+
end
|
54
|
+
if block_given?
|
55
|
+
yield(row_with_typecast)
|
56
|
+
row_count += 1
|
57
|
+
else
|
58
|
+
results << row_with_typecast
|
59
|
+
end
|
60
|
+
end
|
61
|
+
block_given? ? row_count : results
|
62
|
+
ensure
|
63
|
+
rset.close rescue nil
|
64
|
+
stmt.close rescue nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def exec(sql, *bindvars)
|
68
|
+
cs = prepare_call(sql, *bindvars)
|
69
|
+
cs.execute
|
70
|
+
true
|
71
|
+
ensure
|
72
|
+
cs.close rescue nil
|
73
|
+
end
|
74
|
+
|
75
|
+
class Cursor
|
76
|
+
|
77
|
+
def initialize(sql, conn)
|
78
|
+
@sql = sql
|
79
|
+
@connection = conn
|
80
|
+
@params = sql.scan(/\:\w+/)
|
81
|
+
@out_types = {}
|
82
|
+
@out_index = {}
|
83
|
+
@statement = @connection.prepare_call(sql)
|
84
|
+
end
|
85
|
+
|
86
|
+
def bind_param(key, value, type=nil, length=nil, in_out='IN')
|
87
|
+
@connection.set_bind_variable(@statement, key, value, type, length)
|
88
|
+
if in_out =~ /OUT/
|
89
|
+
@out_types[key] = type || value.class
|
90
|
+
@out_index[key] = bind_param_index(key)
|
91
|
+
@statement.registerOutParameter(@out_index[key],@connection.get_java_sql_type(value,type))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def exec
|
96
|
+
@statement.execute
|
97
|
+
end
|
98
|
+
|
99
|
+
def [](key)
|
100
|
+
@connection.get_bind_variable(@statement, @out_index[key], @out_types[key])
|
101
|
+
end
|
102
|
+
|
103
|
+
def close
|
104
|
+
@statement.close
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def bind_param_index(key)
|
110
|
+
return key if key.kind_of? Integer
|
111
|
+
key = ":#{key.to_s}" unless key.to_s =~ /^:/
|
112
|
+
@params.index(key)+1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def parse(sql)
|
117
|
+
Cursor.new(sql, self)
|
118
|
+
end
|
119
|
+
|
120
|
+
def prepare_statement(sql, *bindvars)
|
121
|
+
stmt = raw_connection.prepareStatement(sql)
|
122
|
+
bindvars.each_with_index do |bv, i|
|
123
|
+
set_bind_variable(stmt, i+1, bv)
|
124
|
+
end
|
125
|
+
stmt
|
126
|
+
end
|
127
|
+
|
128
|
+
def prepare_call(sql, *bindvars)
|
129
|
+
stmt = raw_connection.prepareCall(sql)
|
130
|
+
bindvars.each_with_index do |bv, i|
|
131
|
+
set_bind_variable(stmt, i+1, bv)
|
132
|
+
end
|
133
|
+
stmt
|
134
|
+
end
|
135
|
+
|
136
|
+
def get_java_sql_type(value, type)
|
137
|
+
case type ? type.to_s : value.class.to_s
|
138
|
+
when 'Fixnum', 'Bignum', 'Integer'
|
139
|
+
java.sql.Types::INTEGER
|
140
|
+
when 'Float'
|
141
|
+
java.sql.Types::FLOAT
|
142
|
+
when 'BigDecimal'
|
143
|
+
java.sql.Types::NUMERIC
|
144
|
+
when 'String'
|
145
|
+
java.sql.Types::VARCHAR
|
146
|
+
when 'Java::OracleSql::CLOB'
|
147
|
+
Java::oracle.jdbc.OracleTypes::CLOB
|
148
|
+
when 'Date'
|
149
|
+
java.sql.Types::DATE
|
150
|
+
when 'Time'
|
151
|
+
java.sql.Types::DATE
|
152
|
+
when 'DateTime'
|
153
|
+
java.sql.Types::DATE
|
154
|
+
else
|
155
|
+
java.sql.Types::VARCHAR
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def set_bind_variable(stmt, i, value, type=nil, length=nil)
|
160
|
+
key = i.kind_of?(Integer) ? nil : i.to_s.gsub(':','')
|
161
|
+
case !value.nil? && type ? type.to_s : value.class.to_s
|
162
|
+
when 'Fixnum', 'Bignum', 'Integer'
|
163
|
+
stmt.send("setInt#{key && "AtName"}", key || i, value)
|
164
|
+
when 'Float'
|
165
|
+
stmt.send("setFloat#{key && "AtName"}", key || i, value)
|
166
|
+
when 'BigDecimal'
|
167
|
+
stmt.send("setBigDecimal#{key && "AtName"}", key || i, java.math.BigDecimal.new(value.to_s))
|
168
|
+
when 'String'
|
169
|
+
stmt.send("setString#{key && "AtName"}", key || i, value)
|
170
|
+
when 'Java::OracleSql::CLOB'
|
171
|
+
stmt.send("setClob#{key && "AtName"}", key || i, value)
|
172
|
+
when 'Date'
|
173
|
+
stmt.send("setDate#{key && "AtName"}", key || i, java.sql.Date.new(Time.parse(value.to_s).to_i*1000))
|
174
|
+
when 'Time'
|
175
|
+
stmt.send("setTime#{key && "AtName"}", key || i, java.sql.Time.new(value.to_i*1000))
|
176
|
+
when 'DateTime'
|
177
|
+
stmt.send("setTime#{key && "AtName"}", key || i, java.sql.Time.new(Time.parse(value.strftime("%c")).to_i*1000))
|
178
|
+
when 'NilClass'
|
179
|
+
stmt.send("setNull#{key && "AtName"}", key || i, get_java_sql_type(value, type))
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def get_bind_variable(stmt, i, type)
|
184
|
+
case type.to_s
|
185
|
+
when 'Fixnum', 'Bignum', 'Integer'
|
186
|
+
stmt.getInt(i)
|
187
|
+
when 'Float'
|
188
|
+
stmt.getFloat(i)
|
189
|
+
when 'BigDecimal'
|
190
|
+
bd = stmt.getBigDecimal(i)
|
191
|
+
bd && BigDecimal.new(bd.to_s)
|
192
|
+
when 'String'
|
193
|
+
stmt.getString(i)
|
194
|
+
when 'Java::OracleSql::CLOB'
|
195
|
+
stmt.getClob(i)
|
196
|
+
when 'Date','Time','DateTime'
|
197
|
+
ts = stmt.getTimestamp(i)
|
198
|
+
# ts && Time.parse(Time.at(ts.getTime/1000).iso8601)
|
199
|
+
ts && Time.local(1900+ts.year, ts.month+1, ts.date, ts.hours, ts.minutes, ts.seconds)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def get_ruby_value_from_result_set(rset, i, type_name)
|
204
|
+
case type_name
|
205
|
+
when "CHAR", "VARCHAR2"
|
206
|
+
rset.getString(i)
|
207
|
+
when "CLOB"
|
208
|
+
ora_value_to_ruby_value(rset.getClob(i))
|
209
|
+
when "NUMBER"
|
210
|
+
d = rset.getBigDecimal(i)
|
211
|
+
if d.nil?
|
212
|
+
nil
|
213
|
+
elsif d.scale == 0
|
214
|
+
d.longValue
|
215
|
+
else
|
216
|
+
d.doubleValue
|
217
|
+
end
|
218
|
+
when "DATE", "TIMESTAMP"
|
219
|
+
Time.at(rset.getTimestamp(i).getTime/1000)
|
220
|
+
else
|
221
|
+
nil
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def plsql_to_ruby_data_type(data_type, data_length)
|
226
|
+
case data_type
|
227
|
+
when "VARCHAR2"
|
228
|
+
[String, data_length || 4000]
|
229
|
+
when "CLOB"
|
230
|
+
[Java::OracleSql::CLOB, nil]
|
231
|
+
when "NUMBER"
|
232
|
+
[BigDecimal, nil]
|
233
|
+
when "DATE"
|
234
|
+
[Time, nil]
|
235
|
+
when "TIMESTAMP"
|
236
|
+
[Time, nil]
|
237
|
+
# CLOB
|
238
|
+
# BLOB
|
239
|
+
else
|
240
|
+
[String, 4000]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def ruby_value_to_ora_value(val, type)
|
245
|
+
if type == BigDecimal
|
246
|
+
val.nil? || val.is_a?(Fixnum) ? val : val.to_f
|
247
|
+
elsif type == Time
|
248
|
+
date_to_time(val)
|
249
|
+
elsif type == Java::OracleSql::CLOB
|
250
|
+
if val
|
251
|
+
clob = Java::OracleSql::CLOB.createTemporary(raw_connection, false, Java::OracleSql::CLOB::DURATION_SESSION)
|
252
|
+
clob.setString(1,val)
|
253
|
+
clob
|
254
|
+
else
|
255
|
+
Java::OracleSql::CLOB.getEmptyCLOB
|
256
|
+
end
|
257
|
+
else
|
258
|
+
val
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def ora_value_to_ruby_value(val)
|
263
|
+
case val
|
264
|
+
when Float, BigDecimal
|
265
|
+
ora_number_to_ruby_number(val)
|
266
|
+
# when OraDate
|
267
|
+
# ora_date_to_ruby_date(val)
|
268
|
+
when Java::OracleSql::CLOB
|
269
|
+
if val.isEmptyLob
|
270
|
+
nil
|
271
|
+
else
|
272
|
+
val.getSubString(1, val.length)
|
273
|
+
end
|
274
|
+
else
|
275
|
+
val
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
private
|
280
|
+
|
281
|
+
def ora_number_to_ruby_number(num)
|
282
|
+
num.to_i == num.to_f ? num.to_i : num.to_f
|
283
|
+
end
|
284
|
+
|
285
|
+
# def ora_date_to_ruby_date(val)
|
286
|
+
# val.to_time
|
287
|
+
# end
|
288
|
+
|
289
|
+
def date_to_time(val)
|
290
|
+
case val
|
291
|
+
when Time
|
292
|
+
val
|
293
|
+
when DateTime
|
294
|
+
Time.parse(val.strftime("%c"))
|
295
|
+
when Date
|
296
|
+
Time.parse(val.strftime("%c"))
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module PLSQL
|
2
|
+
class OCIConnection < Connection
|
3
|
+
|
4
|
+
def logoff
|
5
|
+
raw_connection.logoff
|
6
|
+
end
|
7
|
+
|
8
|
+
def commit
|
9
|
+
raw_connection.commit
|
10
|
+
end
|
11
|
+
|
12
|
+
def rollback
|
13
|
+
raw_connection.rollback
|
14
|
+
end
|
15
|
+
|
16
|
+
def autocommit?
|
17
|
+
raw_connection.autocommit?
|
18
|
+
end
|
19
|
+
|
20
|
+
def autocommit=(value)
|
21
|
+
raw_connection.autocommit = value
|
22
|
+
end
|
23
|
+
|
24
|
+
def select_first(sql, *bindvars)
|
25
|
+
cursor = raw_connection.exec(sql, *bindvars)
|
26
|
+
result = cursor.fetch
|
27
|
+
if result
|
28
|
+
result.map { |val| ora_value_to_ruby_value(val) }
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
ensure
|
33
|
+
cursor.close rescue nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def select_all(sql, *bindvars, &block)
|
37
|
+
cursor = raw_connection.exec(sql, *bindvars)
|
38
|
+
results = []
|
39
|
+
row_count = 0
|
40
|
+
while row = cursor.fetch
|
41
|
+
row_with_typecast = row.map {|val| ora_value_to_ruby_value(val) }
|
42
|
+
if block_given?
|
43
|
+
yield(row_with_typecast)
|
44
|
+
row_count += 1
|
45
|
+
else
|
46
|
+
results << row_with_typecast
|
47
|
+
end
|
48
|
+
end
|
49
|
+
block_given? ? row_count : results
|
50
|
+
ensure
|
51
|
+
cursor.close rescue nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def exec(sql, *bindvars)
|
55
|
+
raw_connection.exec(sql, *bindvars)
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
class Cursor
|
60
|
+
attr_accessor :raw_cursor
|
61
|
+
|
62
|
+
def initialize(raw_cur)
|
63
|
+
@raw_cursor = raw_cur
|
64
|
+
end
|
65
|
+
|
66
|
+
def bind_param(key, value, type=nil, length=nil, in_out='IN')
|
67
|
+
raw_cursor.bind_param(key, value, type, length)
|
68
|
+
end
|
69
|
+
|
70
|
+
def exec(*bindvars)
|
71
|
+
raw_cursor.exec(*bindvars)
|
72
|
+
end
|
73
|
+
|
74
|
+
def [](key)
|
75
|
+
raw_cursor[key]
|
76
|
+
end
|
77
|
+
|
78
|
+
def close
|
79
|
+
raw_cursor.close
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse(sql)
|
84
|
+
Cursor.new(raw_connection.parse(sql))
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def plsql_to_ruby_data_type(data_type, data_length)
|
89
|
+
case data_type
|
90
|
+
when "VARCHAR2"
|
91
|
+
[String, data_length || 4000]
|
92
|
+
when "CLOB"
|
93
|
+
[OCI8::CLOB, nil]
|
94
|
+
when "NUMBER"
|
95
|
+
[OraNumber, nil]
|
96
|
+
when "DATE"
|
97
|
+
[DateTime, nil]
|
98
|
+
when "TIMESTAMP"
|
99
|
+
[Time, nil]
|
100
|
+
# CLOB
|
101
|
+
# BLOB
|
102
|
+
else
|
103
|
+
[String, 4000]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def ruby_value_to_ora_value(val, type)
|
108
|
+
if type == OraNumber
|
109
|
+
val.nil? || val.is_a?(Fixnum) ? val : val.to_f
|
110
|
+
elsif type == DateTime
|
111
|
+
val ? val.to_datetime : nil
|
112
|
+
elsif type == OCI8::CLOB
|
113
|
+
# ruby-oci8 cannot create CLOB from ''
|
114
|
+
val = nil if val == ''
|
115
|
+
OCI8::CLOB.new(raw_oci_connection, val)
|
116
|
+
else
|
117
|
+
val
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def ora_value_to_ruby_value(val)
|
122
|
+
case val
|
123
|
+
when Float, OraNumber
|
124
|
+
ora_number_to_ruby_number(val)
|
125
|
+
when DateTime, OraDate
|
126
|
+
ora_date_to_ruby_date(val)
|
127
|
+
when OCI8::CLOB
|
128
|
+
val.rewind
|
129
|
+
val.read
|
130
|
+
else
|
131
|
+
val
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def raw_oci_connection
|
139
|
+
if raw_connection.is_a? OCI8
|
140
|
+
raw_connection
|
141
|
+
# ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
|
142
|
+
# in this case we need to pass original OCI8 connection
|
143
|
+
else
|
144
|
+
raw_connection.instance_variable_get(:@connection)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def ora_number_to_ruby_number(num)
|
149
|
+
num.to_i == num.to_f ? num.to_i : num.to_f
|
150
|
+
end
|
151
|
+
|
152
|
+
def ora_date_to_ruby_date(val)
|
153
|
+
case val
|
154
|
+
when DateTime
|
155
|
+
Time.parse(val.strftime("%c")) rescue val
|
156
|
+
when OraDate
|
157
|
+
val.to_time rescue val.to_datetime
|
158
|
+
else
|
159
|
+
val
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|