ruby-oci8 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/ChangeLog +569 -0
  2. data/Makefile +51 -0
  3. data/NEWS +322 -0
  4. data/README +415 -0
  5. data/VERSION +1 -0
  6. data/dist-files +70 -0
  7. data/doc/api.en.html +527 -0
  8. data/doc/api.en.rd +554 -0
  9. data/doc/api.ja.html +525 -0
  10. data/doc/api.ja.rd +557 -0
  11. data/doc/manual.css +35 -0
  12. data/ext/oci8/MANIFEST +22 -0
  13. data/ext/oci8/attr.c +415 -0
  14. data/ext/oci8/bind.c +194 -0
  15. data/ext/oci8/const.c +165 -0
  16. data/ext/oci8/define.c +53 -0
  17. data/ext/oci8/describe.c +81 -0
  18. data/ext/oci8/descriptor.c +39 -0
  19. data/ext/oci8/env.c +276 -0
  20. data/ext/oci8/error.c +234 -0
  21. data/ext/oci8/extconf.rb +118 -0
  22. data/ext/oci8/handle.c +262 -0
  23. data/ext/oci8/lob.c +386 -0
  24. data/ext/oci8/oci8.c +137 -0
  25. data/ext/oci8/oci8.h +345 -0
  26. data/ext/oci8/ocinumber.c +117 -0
  27. data/ext/oci8/oraconf.rb +1026 -0
  28. data/ext/oci8/oradate.c +426 -0
  29. data/ext/oci8/oranumber.c +445 -0
  30. data/ext/oci8/param.c +37 -0
  31. data/ext/oci8/post-config.rb +5 -0
  32. data/ext/oci8/server.c +182 -0
  33. data/ext/oci8/session.c +99 -0
  34. data/ext/oci8/stmt.c +624 -0
  35. data/ext/oci8/svcctx.c +229 -0
  36. data/lib/DBD/OCI8/OCI8.rb +549 -0
  37. data/lib/oci8.rb.in +1605 -0
  38. data/metaconfig +142 -0
  39. data/pre-distclean.rb +7 -0
  40. data/ruby-oci8.gemspec +54 -0
  41. data/ruby-oci8.spec +62 -0
  42. data/setup.rb +1331 -0
  43. data/support/README +4 -0
  44. data/support/runit/assert.rb +281 -0
  45. data/support/runit/cui/testrunner.rb +101 -0
  46. data/support/runit/error.rb +4 -0
  47. data/support/runit/method_mappable.rb +20 -0
  48. data/support/runit/robserver.rb +25 -0
  49. data/support/runit/setuppable.rb +15 -0
  50. data/support/runit/teardownable.rb +16 -0
  51. data/support/runit/testcase.rb +113 -0
  52. data/support/runit/testfailure.rb +25 -0
  53. data/support/runit/testresult.rb +121 -0
  54. data/support/runit/testsuite.rb +43 -0
  55. data/support/runit/version.rb +3 -0
  56. data/test/README +4 -0
  57. data/test/config.rb +129 -0
  58. data/test/test_all.rb +43 -0
  59. data/test/test_bind_raw.rb +53 -0
  60. data/test/test_bind_time.rb +191 -0
  61. data/test/test_break.rb +81 -0
  62. data/test/test_clob.rb +101 -0
  63. data/test/test_connstr.rb +80 -0
  64. data/test/test_dbi.rb +317 -0
  65. data/test/test_dbi_clob.rb +56 -0
  66. data/test/test_describe.rb +137 -0
  67. data/test/test_metadata.rb +243 -0
  68. data/test/test_oci8.rb +273 -0
  69. data/test/test_oradate.rb +263 -0
  70. data/test/test_oranumber.rb +149 -0
  71. metadata +118 -0
@@ -0,0 +1,554 @@
1
+ =begin
2
+ = Ruby/OCI8 High-level API
3
+ [ ((<Home|URL:index.en.html>)) ] [ English | ((<Japanese|URL:api.ja.html>)) ]
4
+
5
+ Ruby/OCI8 is divided to two layer APIs. One is "Low-level
6
+ API". The other is "High-level API". This document describes how to
7
+ use the latter, but some of the former will be described as long as it
8
+ is necessary to use the latter.
9
+
10
+ "High-level API" is the library written by ruby, which based on
11
+ "Low-level API". This API hides complicated structure of OCI and make
12
+ it easy to issue SQL statements as possible. Please use this for general purpose.
13
+
14
+ "Low-level API" is the library written by C language. OCI ((-Oracle
15
+ Call Interface-)) handles and OCI functions become ruby's classes
16
+ and methods respectively. The handles and functions are converted by
17
+ straight mapping rule as long as ruby's syntax allows.
18
+
19
+ In the version 0.2 I will rewrite High-level API by C language directly.
20
+ Low-level API will be obsolete.
21
+
22
+ == Contents
23
+ * ((<Classes List>))
24
+ * ((<OCI8>))
25
+ * ((<OCI8::Cursor>))
26
+ * ((<OCI8::BLOB>))
27
+ * ((<OCI Exception Classes>))
28
+ * ((<Methods List>))
29
+ * OCI8
30
+ * ((<new|OCI8.new>))(userid, password, dbname = nil, privilege = nil)
31
+ * ((<logoff|OCI8#logoff>))()
32
+ * ((<exec|OCI8#exec>))(sql, *bindvars)
33
+ * ((<parse|OCI8#parse>))(sql)
34
+ * ((<commit|OCI8#commit>))()
35
+ * ((<rollback|OCI8#rollback>))()
36
+ * ((<autocommit?|OCI8#autocommit?>))
37
+ * ((<autocommit|OCI8#autocommit>))
38
+ * ((<autocommit=|OCI8#autocommit=>))
39
+ * ((<non_blocking?|OCI8#non_blocking?>))
40
+ * ((<non_blocking=|OCI8#non_blocking=>))
41
+ * ((<break|OCI8#break>))()
42
+ * OCI8::Cursor
43
+ * ((<define|OCI8::Cursor#define>))(pos, type, length = nil)
44
+ * ((<bind_param|OCI8::Cursor#bind_param>))(key, val, type = nil, length = nil)
45
+ * ((<[]|OCI8::Cursor#[]>))(key)
46
+ * ((<[]=|OCI8::Cursor#[]=>))(key, val)
47
+ * ((<keys|OCI8::Cursor#keys>))()
48
+ * ((<exec|OCI8::Cursor#exec>))(*bindvars)
49
+ * ((<type|OCI8::Cursor#type>))
50
+ * ((<row_count|OCI8::Cursor#row_count>))
51
+ * ((<get_col_names|OCI8::Cursor#get_col_names>))
52
+ * ((<getColNames|OCI8::Cursor#getColNames>))
53
+ * ((<fetch|OCI8::Cursor#fetch>))()
54
+ * ((<close|OCI8::Cursor#close>))()
55
+ * ((<rowid|OCI8::Cursor#rowid>))
56
+ * OCI8::BLOB
57
+ * ((<available?|OCI8::BLOB#available?>))
58
+ * ((<read|OCI8::BLOB#read>))(size = nil)
59
+ * ((<write|OCI8::BLOB#write>))(data)
60
+ * ((<size|OCI8::BLOB#size>))
61
+ * ((<size=|OCI8::BLOB#size=>))(len)
62
+ * ((<chunk_size|OCI8::BLOB#chunk_size>))
63
+ * ((<truncate|OCI8::BLOB#truncate>))(len)
64
+ * ((<pos|OCI8::BLOB#pos>))
65
+ * ((<pos=|OCI8::BLOB#pos=>))(pos)
66
+ * ((<tell|OCI8::BLOB#tell>))
67
+ * ((<seek|OCI8::BLOB#seek>))(pos)
68
+ * ((<rewind|OCI8::BLOB#rewind>))
69
+ * ((<eof?|OCI8::BLOB#eof?>))
70
+ * ((<Appendix>))
71
+ * ((<"Blocking/Non-Blocking Mode">))
72
+ == Classes List
73
+ Indispensable Classes to use high-level API are ((<OCI8>)),
74
+ ((<OCI8::Cursor>)), ((<OCI8::BLOB>)) and ((<OCI Exception Classes>)).
75
+
76
+ === OCI8
77
+ The instance of this class corresponds to the connection with
78
+ database, which corresponds to java.sql.Connection of JDBC and
79
+ database handle $dbh of Perl/DBI.
80
+
81
+ To execute simple SQL, it can perform by this class only.
82
+
83
+ === OCI8::Cursor
84
+ The instance of this class corresponds to cursor in the term of
85
+ Oracle, which corresponds to java.sql.Statement of JDBC and statement
86
+ handle $sth of Perl/DBI.
87
+
88
+ Don't create the instance by calling 'new' method. Please create it by
89
+ calling ((<OCI8#exec>)) or ((<OCI8#parse>)).
90
+
91
+ === OCI8::BLOB
92
+ This is a lob locator to read/write binary data to/from BLOB column.
93
+ This instance is automatically generated by select statement.
94
+
95
+ === OCI Exception Classes
96
+ The class hierarchy of OCI exception class used in high-level API is
97
+ as follows.
98
+
99
+ * ((|OCIException|))
100
+ * ((|OCIError|))
101
+ * ((|OCIInvalidHandle|))
102
+ * ((|OCIBreak|))
103
+
104
+ ((|OCIException|)) is the abstract class for all OCI exceptions. To
105
+ rescue all OCI exceptions, please use this class.
106
+
107
+ ((|OCIError|)) is the exception class with Oracle's error code. You
108
+ get the error message by OCIError#message. The error code by
109
+ OCIError#code.
110
+
111
+ ((|OCIInvalidHandle|)) is raised when OCI call is performed to
112
+ the invalid handle.
113
+
114
+ ((|OCIBreak|)) is raised when the OCI call is canceled by other thread.
115
+ See also ((<"Blocking/Non-Blocking Mode">)).
116
+
117
+ == Methods List
118
+ === OCI8
119
+ --- OCI8.new(userid, password, dbname = nil, privilege = nil)
120
+ Connects to Oracle by userid and password. dbname is the connect
121
+ string of Net8. If you need DBA privilege, please set privilege
122
+ as :SYSDBA or :SYSOPER.
123
+
124
+ example:
125
+ # sqlplus scott/tiger@orcl.world
126
+ conn = OCI8.new("scott", "tiger", "orcl.world")
127
+
128
+ example:
129
+ # sqlplus 'sys/change_on_install as sysdba'
130
+ conn = OCI8.new("sys", "change_on_install", nil, :SYSDBA)
131
+
132
+ --- OCI8#logoff()
133
+ Disconnects from Oracle. Uncommitted transaction will be
134
+ rollbacked.
135
+
136
+ example:
137
+ conn = OCI8.new("scott", "tiger")
138
+ ... do something ...
139
+ conn.logoff
140
+
141
+ --- OCI8#exec(sql, *bindvars)
142
+ Executes the sql statement. The type of return value depends on
143
+ the type of sql statement: select; insert, update and delete;
144
+ create, alter and drop; and PL/SQL.
145
+
146
+ When bindvars are specified, they are bound as bind variables
147
+ before execution.
148
+
149
+ In case of select statement with no block, it returns the
150
+ instance of OCI8::Cursor.
151
+
152
+ example:
153
+ conn = OCI8.new('scott', 'tiger')
154
+ cursor = conn.exec('SELECT * FROM emp')
155
+ while r = cursor.fetch()
156
+ puts r.join(',')
157
+ end
158
+ cursor.close
159
+ conn.logoff
160
+
161
+ In case of select statement with a block, it acts as iterator and
162
+ returns the processed row counts. Fetched data is passed to the
163
+ block as array. NULL value becomes nil in ruby.
164
+
165
+ example:
166
+ conn = OCI8.new('scott', 'tiger')
167
+ num_rows = conn.exec('SELECT * FROM emp') do |r|
168
+ puts r.join(',')
169
+ end
170
+ puts num_rows.to_s + ' rows were processed.'
171
+ conn.logoff
172
+
173
+ In case of insert, update or delete statement, it returns the
174
+ number of processed rows.
175
+
176
+ example:
177
+ conn = OCI8.new('scott', 'tiger')
178
+ num_rows = conn.exec('UPDATE emp SET sal = sal * 1.1')
179
+ puts num_rows.to_s + ' rows were updated.'
180
+ conn.logoff
181
+
182
+ In case of create, alter or drop statement, it returns true.
183
+
184
+ example:
185
+ conn = OCI8.new('scott', 'tiger')
186
+ conn.exec('CREATE TABLE test (col1 CHAR(6))')
187
+ conn.logoff
188
+
189
+ In case of PL/SQL statement, it returns the array of bind
190
+ variables.
191
+
192
+ example:
193
+ conn = OCI8.new('scott', 'tiger')
194
+ conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123)
195
+ # => ["0123", 123]
196
+ conn.logoff
197
+
198
+ Above example uses two bind variables which names are ((|:str|))
199
+ and ((|:num|)). These initial values are "the string whose width
200
+ is 4 and whose value is 'ABCD'" and "the number whose value is
201
+ 123". This method returns the array of these bind variables,
202
+ which may modified by PL/SQL statement. The order of array is
203
+ same with that of bind variables.
204
+
205
+ --- OCI8#parse(sql)
206
+ Creates cursor, prepare to execute SQL statement and return the
207
+ instance of OCI8::Cursor.
208
+
209
+ --- OCI8#commit()
210
+ Commits the transaction.
211
+
212
+ example:
213
+ conn = OCI8.new("scott", "tiger")
214
+ conn.exec("UPDATE emp SET sal = sal * 1.1") # yahoo
215
+ conn.commit
216
+ conn.logoff
217
+
218
+ --- OCI8#rollback()
219
+ Rollbacks the transaction.
220
+
221
+ example:
222
+ conn = OCI8.new("scott", "tiger")
223
+ conn.exec("UPDATE emp SET sal = sal * 0.9") # boos
224
+ conn.rollback
225
+ conn.logoff
226
+
227
+ --- OCI8#autocommit?
228
+ Returns the state of the autocommit mode. The default value is
229
+ false. If true, the transaction is committed automatically
230
+ whenever executing insert/update/delete statements.
231
+
232
+ --- OCI8#autocommit
233
+ Alias of ((<OCI8#autocommit?>)).
234
+
235
+ --- OCI8#autocommit=
236
+ Changes the status of the autocommit mode. Acceptable values are
237
+ true and false.
238
+
239
+ example:
240
+ conn = OCI8.new("scott", "tiger")
241
+ conn.autocommit = true
242
+ ... do something ...
243
+ conn.logoff
244
+
245
+ --- OCI8#non_blocking?
246
+ Returns the status of blocking/non-blocking mode. The default
247
+ value is false, that is blocking mode. See
248
+ ((<"Blocking/Non-Blocking Mode">)).
249
+
250
+ --- OCI8#non_blocking=
251
+ Changes the status of blocking/non-blocking mode. Acceptable
252
+ values are true and false. See
253
+ ((<"Blocking/Non-Blocking Mode">)).
254
+
255
+ --- OCI8#break()
256
+ Cancels the OCI call performing in other thread. To use this, the
257
+ connection status must be non-blocking mode. See
258
+ ((<"Blocking/Non-Blocking Mode">)).
259
+
260
+ == OCI8::Cursor
261
+ --- OCI8::Cursor#define(pos, type, length = nil)
262
+
263
+ explicitly indicate the date type of fetched value. run this
264
+ method within parse and exec. pos starts from 1. lentgh is used
265
+ when type is String.
266
+
267
+ example:
268
+ cursor = conn.parse("SELECT ename, hiredate FROM emp")
269
+ cursor.define(1, String, 20) # fetch the first column as String.
270
+ cursor.define(2, Time) # fetch the second column as Time.
271
+ cursor.exec()
272
+
273
+ --- OCI8::Cursor#bind_param(key, val, type = nil, length = nil)
274
+ Binds variables explicitly.
275
+
276
+ When key is number, it binds by position, which starts from 1.
277
+ When key is string, it binds by the name of placeholder.
278
+
279
+ example:
280
+ cursor = conn.parse("SELECT * FROM emp WHERE ename = :ename")
281
+ cursor.bind_param(1, 'SMITH') # bind by position
282
+ ...or...
283
+ cursor.bind_param(':ename', 'SMITH') # bind by name
284
+
285
+ To bind as number, Fixnum and Float are available, but Bignum is
286
+ not supported. If its initial value is NULL, please set nil to
287
+ ((|type|)) and Fixnum or Float to ((|val|)).
288
+
289
+ example:
290
+ cursor.bind_param(1, 1234) # bind as Fixnum, Initial value is 1234.
291
+ cursor.bind_param(1, 1234.0) # bind as Float, Initial value is 1234.0.
292
+ cursor.bind_param(1, nil, Fixnum) # bind as Fixnum, Initial value is NULL.
293
+ cursor.bind_param(1, nil, Float) # bind as Float, Initial value is NULL.
294
+
295
+ In case of binding a string, set the string itself to
296
+ ((|val|)). When the bind variable is used as output, set the
297
+ string whose length is enough to store or set the length.
298
+
299
+ example:
300
+ cursor = conn.parse("BEGIN :out := :in || '_OUT'; END;")
301
+ cursor.bind_param(':in', 'DATA') # bind as String with width 4.
302
+ cursor.bind_param(':out', nil, String, 7) # bind as String with width 7.
303
+ cursor.exec()
304
+ p cursor[':out'] # => 'DATA_OU'
305
+ # Though the length of :out is 8 bytes in PL/SQL block, it is
306
+ # bound as 7 bytes. So result is cut off at 7 byte.
307
+
308
+ In case of binding a string as RAW, set OCI::RAW to ((|type|)).
309
+
310
+ example:
311
+ cursor = conn.parse("INSERT INTO raw_table(raw_column) VALUE (:1)")
312
+ cursor.bind_param(1, 'RAW_STRING', OCI8::RAW)
313
+ cursor.exec()
314
+ cursor.close()
315
+
316
+ --- OCI8::Cursor#[](key)
317
+ Gets the value of the bind variable.
318
+
319
+ In case of binding explicitly, use same key with that of
320
+ ((<OCI8::Cursor#bind_param>)). A placeholder can be bound by
321
+ name or position. If you bind by name, use that name. If you bind
322
+ by position, use the position.
323
+
324
+ example:
325
+ cursor = conn.parse("BEGIN :out := 'BAR'; END;")
326
+ cursor.bind_param(':out', 'FOO') # bind by name
327
+ p cursor[':out'] # => 'FOO'
328
+ p cursor[1] # => nil
329
+ cursor.exec()
330
+ p cursor[':out'] # => 'BAR'
331
+ p cursor[1] # => nil
332
+
333
+ example:
334
+ cursor = conn.parse("BEGIN :out := 'BAR'; END;")
335
+ cursor.bind_param(1, 'FOO') # bind by position
336
+ p cursor[':out'] # => nil
337
+ p cursor[1] # => 'FOO'
338
+ cursor.exec()
339
+ p cursor[':out'] # => nil
340
+ p cursor[1] # => 'BAR'
341
+
342
+ In case of binding by ((<OCI8#exec>)) or ((<OCI8::Cursor#exec>)),
343
+ get the value by position, which starts from 1.
344
+
345
+ example:
346
+ cursor = conn.exec("BEGIN :out := 'BAR'; END;", 'FOO')
347
+ # 1st bind variable is bound as String with width 3. Its initial value is 'FOO'
348
+ # After execute, the value become 'BAR'.
349
+ p cursor[1] # => 'BAR'
350
+
351
+ --- OCI8::Cursor#[]=(key, val)
352
+ Sets the value to the bind variable. The way to specify the
353
+ ((|key|)) is same with ((<OCI8::Cursor#[]>)). This is available
354
+ to replace the value and execute many times.
355
+
356
+ example1:
357
+ cursor = conn.parse("INSERT INTO test(col1) VALUES(:1)")
358
+ cursor.bind_params(1, nil, String, 3)
359
+ ['FOO', 'BAR', 'BAZ'].each do |key|
360
+ cursor[1] = key
361
+ cursor.exec
362
+ end
363
+ cursor.close()
364
+
365
+ example2:
366
+ ['FOO', 'BAR', 'BAZ'].each do |key|
367
+ conn.exec("INSERT INTO test(col1) VALUES(:1)", key)
368
+ end
369
+
370
+ Both example's results are same. But the former will use less resources.
371
+
372
+ --- OCI8::Cursor#keys()
373
+ Returns the keys of bind variables as array.
374
+
375
+ --- OCI8::Cursor#exec(*bindvars)
376
+ Executes the SQL statement assigned the cursor. The type of
377
+ return value depends on the type of sql statement: select;
378
+ insert, update and delete; create, alter, drop and PL/SQL.
379
+
380
+ In case of select statement, it returns the number of the
381
+ select-list.
382
+
383
+ In case of insert, update or delete statement, it returns the
384
+ number of processed rows.
385
+
386
+ In case of create, alter, drop and PL/SQL statement, it returns
387
+ true. In contrast with ((<OCI8#exec>)), it returns true even
388
+ though PL/SQL. Use ((<OCI8::Cursor#[]>)) explicitly to get bind
389
+ variables.
390
+
391
+ --- OCI8::Cursor#type
392
+ gets the type of SQL statement. Its value is one of the follows.
393
+ * OCI8::STMT_SELECT
394
+ * OCI8::STMT_UPDATE
395
+ * OCI8::STMT_DELETE
396
+ * OCI8::STMT_INSERT
397
+ * OCI8::STMT_CREATE
398
+ * OCI8::STMT_DROP
399
+ * OCI8::STMT_ALTER
400
+ * OCI8::STMT_BEGIN
401
+ * OCI8::STMT_DECLARE
402
+ For PL/SQL statement, it returns OCI8::STMT_BEGIN or
403
+ OCI8::STMT_DECLARE.
404
+
405
+ --- OCI8::Cursor#row_count
406
+ Returns the number of processed rows.
407
+
408
+ --- OCI8::Cursor#get_col_names
409
+ Gets the names of select-list as array. Please use this
410
+ method after exec.
411
+
412
+ --- OCI8::Cursor#getColNames
413
+ Alias of ((<OCI8::Cursor#get_col_names>)).
414
+
415
+ --- OCI8::Cursor#fetch()
416
+ Gets fetched data as array. This is available for select
417
+ statement only.
418
+
419
+ example:
420
+ conn = OCI8.new('scott', 'tiger')
421
+ cursor = conn.exec('SELECT * FROM emp')
422
+ while r = cursor.fetch()
423
+ puts r.join(',')
424
+ end
425
+ cursor.close
426
+ conn.logoff
427
+
428
+ --- OCI8::Cursor#close()
429
+ close the cursor.
430
+
431
+ --- OCI8::Cursor#rowid()
432
+ get the rowid of the last processed row.
433
+ This value is available as bind data.
434
+ On the other hand it isn't available for other purpose.
435
+
436
+ == OCI8::BLOB
437
+ --- OCI8::BLOB#available?
438
+ check whether BLOB is available or not.
439
+ To use BLOB you need to insert EMPTY_BLOB() at first.
440
+
441
+ example:
442
+ conn.exec("CREATE TABLE photo (name VARCHAR2(50), image BLOB)")
443
+ conn.exec("INSERT INTO photo VALUES ('null-data', NULL)")
444
+ conn.exec("INSERT INTO photo VALUES ('empty-data', EMPTY_BLOB())")
445
+ conn.exec("SELECT name, image FROM photo") do |name, image|
446
+ case name
447
+ when 'null-data'
448
+ puts "#{name} => #{image.available?.to_s}"
449
+ # => false
450
+ when 'empty-data'
451
+ puts "#{name} => #{image.available?.to_s}"
452
+ # => true
453
+ end
454
+ end
455
+
456
+ --- OCI8::BLOB#read(size = nil)
457
+ read at most size bytes from BLOB, or to the end of file if size is omitted.
458
+
459
+ example: read chunks of chunk size.
460
+ conn.exec("SELECT name, image FROM photo") do |name, image|
461
+ chunk_size = image.chunk_size
462
+ File.open(name, 'w') do |f|
463
+ until image.eof?
464
+ f.write(image.read(chunk_size))
465
+ end
466
+ end
467
+ end
468
+
469
+ example: read at once.
470
+ conn.exec("SELECT name, image FROM photo") do |name, image|
471
+ File.open(name, 'w') do |f|
472
+ f.write(image.read)
473
+ end
474
+ end
475
+
476
+ --- OCI8::BLOB#write(string)
477
+ write the given string to BLOB.
478
+ If old data is longer than new data, resize by ((<OCI8::BLOB#size=>)).
479
+
480
+ example: write chunks of chunk size.
481
+ cursor = conn.parse("INSERT INTO photo VALUES(:name, EMPTY_BLOB())")
482
+ Dir["*.png"].each do |fname|
483
+ cursor.exec(fname)
484
+ end
485
+ conn.exec("SELECT name, image FROM photo") do |name, image|
486
+ chunk_size = image.chunk_size
487
+ File.open(name, 'r') do |f|
488
+ until f.eof?
489
+ image.write(f.read(chunk_size))
490
+ end
491
+ image.size = f.pos
492
+ end
493
+ end
494
+ conn.commit
495
+
496
+ example: write at once.
497
+ conn.exec("SELECT name, image FROM photo") do |name, image|
498
+ File.open(name, 'r') do |f|
499
+ image.write(f.read)
500
+ image.size = f.pos
501
+ end
502
+ end
503
+
504
+ --- OCI8::BLOB#size
505
+ return the size of BLOB.
506
+
507
+ --- OCI8::BLOB#size=(len)
508
+ set the size of BLOB.
509
+
510
+ --- OCI8::BLOB#chunk_size
511
+ return the chunk size of BLOB.
512
+
513
+ --- OCI8::BLOB#truncate(len)
514
+ set the size of BLOB.
515
+
516
+ --- OCI8::BLOB#pos
517
+ return the current offset of BLOB.
518
+
519
+ --- OCI8::BLOB#pos=(pos)
520
+ set the current offset of BLOB.
521
+
522
+ --- OCI8::BLOB#eof?
523
+ return true if BLOB is at end of file
524
+
525
+ --- OCI8::BLOB#tell
526
+ Synonym for ((<OCI8::BLOB#pos>)).
527
+
528
+ --- OCI8::BLOB#seek(pos)
529
+ Synonym for ((<OCI8::BLOB#pos=>)).
530
+
531
+ --- OCI8::BLOB#rewind
532
+ set the current offset to zero.
533
+
534
+ == Appendix
535
+ === Blocking/Non-Blocking Mode
536
+ The default mode is blocking mode. You can change the mode by
537
+ ((<OCI8#non_blocking=>)).
538
+
539
+ When the mode is blocking, heavy OCI calls will block the process
540
+ itself even though multithread application because ruby's thread is
541
+ not native one.
542
+
543
+ when the mode is non-blocking, heavy OCI calls will not block the
544
+ process, but block the thread only. Instead of the merit, each OCI
545
+ call become a bit slower because it polls many times whether the OCI
546
+ call is finished or not.
547
+
548
+ You can cancel a OCI call by using ((<OCI8#break>)) from other thread.
549
+ The canceled OCI call raises ((|OCIBreak|)) exception.
550
+
551
+ Restriction of non-blocking mode: Don't do OCI calls at the same time
552
+ for a same connection.
553
+
554
+ =end