ruby-oci8 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +121 -0
- data/Makefile +11 -4
- data/NEWS +126 -0
- data/VERSION +1 -1
- data/ext/oci8/.document +16 -1
- data/ext/oci8/apiwrap.yml +9 -0
- data/ext/oci8/attr.c +1 -1
- data/ext/oci8/bind.c +1 -38
- data/ext/oci8/extconf.rb +8 -9
- data/ext/oci8/lob.c +5 -3
- data/ext/oci8/object.c +12 -0
- data/ext/oci8/oci8.c +403 -115
- data/ext/oci8/oci8.h +4 -0
- data/ext/oci8/oci8lib.c +10 -1
- data/ext/oci8/ocidatetime.c +47 -5
- data/ext/oci8/ocinumber.c +254 -47
- data/ext/oci8/oraconf.rb +40 -11
- data/ext/oci8/oradate.c +1 -1
- data/lib/.document +0 -1
- data/lib/oci8.rb.in +1 -1
- data/lib/oci8/.document +2 -2
- data/lib/oci8/bindtype.rb +32 -8
- data/lib/oci8/compat.rb +5 -0
- data/lib/oci8/datetime.rb +284 -160
- data/lib/oci8/object.rb +18 -4
- data/lib/oci8/oci8.rb +24 -4
- data/test/test_appinfo.rb +34 -0
- data/test/test_clob.rb +13 -0
- data/test/test_datetime.rb +160 -7
- data/test/test_oci8.rb +31 -3
- data/test/test_oranumber.rb +12 -7
- metadata +3 -3
data/ext/oci8/object.c
CHANGED
@@ -37,6 +37,7 @@ enum {
|
|
37
37
|
ATTR_OCINUMBER,
|
38
38
|
ATTR_FLOAT,
|
39
39
|
ATTR_INTEGER,
|
40
|
+
ATTR_OCIDATE,
|
40
41
|
ATTR_BINARY_DOUBLE,
|
41
42
|
ATTR_BINARY_FLOAT,
|
42
43
|
ATTR_NAMED_TYPE,
|
@@ -167,6 +168,8 @@ static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *dat
|
|
167
168
|
return oci8_make_float((OCINumber *)data, oci8_errhp);
|
168
169
|
case ATTR_INTEGER:
|
169
170
|
return oci8_make_integer((OCINumber *)data, oci8_errhp);
|
171
|
+
case ATTR_OCIDATE:
|
172
|
+
return oci8_make_ocidate((OCIDate *)data);
|
170
173
|
case ATTR_BINARY_DOUBLE:
|
171
174
|
return rb_float_new(*(double*)data);
|
172
175
|
case ATTR_BINARY_FLOAT:
|
@@ -309,6 +312,9 @@ static VALUE oci8_named_coll_set_coll_element(VALUE self, VALUE datatype, VALUE
|
|
309
312
|
OCINumberSetZero(oci8_errhp, &cb_data.data.num);
|
310
313
|
cb_data.indp = &cb_data.ind;
|
311
314
|
break;
|
315
|
+
case ATTR_OCIDATE:
|
316
|
+
cb_data.indp = &cb_data.ind;
|
317
|
+
break;
|
312
318
|
case ATTR_BINARY_DOUBLE:
|
313
319
|
cb_data.data.dbl = 0.0;
|
314
320
|
cb_data.indp = &cb_data.ind;
|
@@ -370,6 +376,7 @@ static VALUE set_coll_element_func(set_coll_element_cb_data_t *cb_data)
|
|
370
376
|
case ATTR_OCINUMBER:
|
371
377
|
case ATTR_FLOAT:
|
372
378
|
case ATTR_INTEGER:
|
379
|
+
case ATTR_OCIDATE:
|
373
380
|
case ATTR_BINARY_DOUBLE:
|
374
381
|
case ATTR_BINARY_FLOAT:
|
375
382
|
elem_ptr = &cb_data->data;
|
@@ -403,6 +410,7 @@ static VALUE set_coll_element_ensure(set_coll_element_cb_data_t *cb_data)
|
|
403
410
|
case ATTR_OCINUMBER:
|
404
411
|
case ATTR_FLOAT:
|
405
412
|
case ATTR_INTEGER:
|
413
|
+
case ATTR_OCIDATE:
|
406
414
|
case ATTR_BINARY_DOUBLE:
|
407
415
|
case ATTR_BINARY_FLOAT:
|
408
416
|
break;
|
@@ -441,6 +449,9 @@ static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data
|
|
441
449
|
case ATTR_INTEGER:
|
442
450
|
oci8_set_integer((OCINumber*)data, val, oci8_errhp);
|
443
451
|
break;
|
452
|
+
case ATTR_OCIDATE:
|
453
|
+
oci8_set_ocidate((OCIDate*)data, val);
|
454
|
+
break;
|
444
455
|
case ATTR_BINARY_DOUBLE:
|
445
456
|
*(double*)data = NUM2DBL(val);
|
446
457
|
break;
|
@@ -592,6 +603,7 @@ void Init_oci_object(VALUE cOCI8)
|
|
592
603
|
rb_define_const(cOCI8TDO, "ATTR_OCINUMBER", INT2FIX(ATTR_OCINUMBER));
|
593
604
|
rb_define_const(cOCI8TDO, "ATTR_FLOAT", INT2FIX(ATTR_FLOAT));
|
594
605
|
rb_define_const(cOCI8TDO, "ATTR_INTEGER", INT2FIX(ATTR_INTEGER));
|
606
|
+
rb_define_const(cOCI8TDO, "ATTR_OCIDATE", INT2FIX(ATTR_OCIDATE));
|
595
607
|
rb_define_const(cOCI8TDO, "ATTR_BINARY_DOUBLE", INT2FIX(ATTR_BINARY_DOUBLE));
|
596
608
|
rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
|
597
609
|
rb_define_const(cOCI8TDO, "ATTR_NAMED_TYPE", INT2FIX(ATTR_NAMED_TYPE));
|
data/ext/oci8/oci8.c
CHANGED
@@ -20,25 +20,16 @@ extern rb_pid_t rb_w32_getpid(void);
|
|
20
20
|
#ifndef OCI_ATTR_CLIENT_IDENTIFIER
|
21
21
|
#define OCI_ATTR_CLIENT_IDENTIFIER 278
|
22
22
|
#endif
|
23
|
+
#ifndef OCI_ATTR_MODULE
|
24
|
+
#define OCI_ATTR_MODULE 366
|
25
|
+
#endif
|
26
|
+
#ifndef OCI_ATTR_ACTION
|
27
|
+
#define OCI_ATTR_ACTION 367
|
28
|
+
#endif
|
29
|
+
#ifndef OCI_ATTR_CLIENT_INFO
|
30
|
+
#define OCI_ATTR_CLIENT_INFO 368
|
31
|
+
#endif
|
23
32
|
|
24
|
-
/*
|
25
|
-
* Document-class: OCI8
|
26
|
-
*
|
27
|
-
* The class to access Oracle database server.
|
28
|
-
*
|
29
|
-
* example:
|
30
|
-
* # output the emp table's content as CSV format.
|
31
|
-
* conn = OCI8.new(username, password)
|
32
|
-
* conn.exec('select * from emp') do |row|
|
33
|
-
* puts row.join(',')
|
34
|
-
* end
|
35
|
-
*
|
36
|
-
* # execute PL/SQL block with bind variables.
|
37
|
-
* conn = OCI8.new(username, password)
|
38
|
-
* conn.exec('BEGIN procedure_name(:1, :2); END;',
|
39
|
-
* value_for_the_first_parameter,
|
40
|
-
* value_for_the_second_parameter)
|
41
|
-
*/
|
42
33
|
static VALUE cOCI8;
|
43
34
|
|
44
35
|
static void oci8_svcctx_free(oci8_base_t *base)
|
@@ -108,7 +99,16 @@ static void oci8_do_parse_connect_string(VALUE conn_str, VALUE *user, VALUE *pas
|
|
108
99
|
}
|
109
100
|
|
110
101
|
/*
|
111
|
-
*
|
102
|
+
* call-seq:
|
103
|
+
* parse_connect_string(string) -> [username, password, dbname, privilege]
|
104
|
+
*
|
105
|
+
* Extracts +username+, +password+, +dbname+ and +privilege+ from the specified +string+.
|
106
|
+
*
|
107
|
+
* example:
|
108
|
+
* "scott/tiger" -> ["scott", "tiger", nil, nil],
|
109
|
+
* "scott/tiger@oradb.example.com" -> ["scott", "tiger", "oradb.example.com", nil]
|
110
|
+
* "sys/change_on_install as sysdba" -> ["sys", "change_on_install", nil, :SYSDBA]
|
111
|
+
*
|
112
112
|
*/
|
113
113
|
static VALUE oci8_parse_connect_string(VALUE self, VALUE conn_str)
|
114
114
|
{
|
@@ -125,30 +125,68 @@ static VALUE oci8_parse_connect_string(VALUE self, VALUE conn_str)
|
|
125
125
|
* call-seq:
|
126
126
|
* new(username, password, dbname = nil, privilege = nil)
|
127
127
|
*
|
128
|
-
*
|
129
|
-
*
|
130
|
-
*
|
131
|
-
*
|
128
|
+
* Connects to an Oracle database server by +username+ and +password+
|
129
|
+
* at +dbname+ as +privilege+.
|
130
|
+
*
|
131
|
+
* === connecting to the local server
|
132
|
+
*
|
133
|
+
* Set +username+ and +password+ or pass "username/password" as a
|
134
|
+
* single argument.
|
135
|
+
*
|
136
|
+
* OCI8.new('scott', 'tiger')
|
137
|
+
* or
|
138
|
+
* OCI8.new('scott/tiger')
|
139
|
+
*
|
140
|
+
* === connecting to a remote server
|
141
|
+
*
|
142
|
+
* Set +username+, +password+ and +dbname+ or pass
|
143
|
+
* "username/password@dbname" as a single argument.
|
144
|
+
*
|
145
|
+
* OCI8.new('scott', 'tiger', 'orcl.world')
|
146
|
+
* or
|
147
|
+
* OCI8.new('scott/tiger@orcl.world')
|
148
|
+
*
|
149
|
+
* The +dbname+ is a net service name or an easy connectection
|
150
|
+
* identifier. The former is a name listed in the file tnsnames.ora.
|
151
|
+
* Ask to your DBA if you don't know what it is. The latter has the
|
152
|
+
* syntax as "//host:port/service_name".
|
153
|
+
*
|
154
|
+
* OCI8.new('scott', 'tiger', '//remote-host:1521/XE')
|
155
|
+
* or
|
156
|
+
* OCI8.new('scott/tiger@//remote-host:1521/XE')
|
132
157
|
*
|
133
|
-
*
|
158
|
+
* === connecting as a privileged user
|
134
159
|
*
|
135
|
-
*
|
160
|
+
* Set :SYSDBA or :SYSOPER to +privilege+, otherwise
|
161
|
+
* "username/password as sysdba" or "username/password as sysoper"
|
162
|
+
* as a single argument.
|
136
163
|
*
|
137
|
-
*
|
138
|
-
*
|
139
|
-
*
|
164
|
+
* OCI8.new('sys', 'change_on_install', nil, :SYSDBA)
|
165
|
+
* or
|
166
|
+
* OCI8.new('sys/change_on_install as sysdba')
|
140
167
|
*
|
141
|
-
*
|
142
|
-
* # sqlplus scott/tiger@orcl.world
|
143
|
-
* conn = OCI8.new("scott", "tiger", "orcl.world")
|
168
|
+
* === external OS authentication
|
144
169
|
*
|
145
|
-
*
|
146
|
-
* # sqlplus scott/tiger@//localhost:1521/XE
|
147
|
-
* conn = OCI8.new("scott", "tiger", "//localhost:1521/XE")
|
170
|
+
* Set nil to +username+ and +password+, or "/" as a single argument.
|
148
171
|
*
|
149
|
-
*
|
150
|
-
*
|
151
|
-
*
|
172
|
+
* OCI8.new(nil, nil)
|
173
|
+
* or
|
174
|
+
* OCI8.new('/')
|
175
|
+
*
|
176
|
+
* To connect to a remote host:
|
177
|
+
*
|
178
|
+
* OCI8.new(nil, nil, 'dbname')
|
179
|
+
* or
|
180
|
+
* OCI8.new('/@dbname')
|
181
|
+
*
|
182
|
+
* === proxy authentication
|
183
|
+
*
|
184
|
+
* Enclose end user's username with square brackets and add it at the
|
185
|
+
* end of proxy user's username.
|
186
|
+
*
|
187
|
+
* OCI8.new('proxy_user_name[end_user_name]', 'proxy_password')
|
188
|
+
* or
|
189
|
+
* OCI8.new('proxy_user_name[end_user_name]/proxy_password')
|
152
190
|
*
|
153
191
|
*/
|
154
192
|
static VALUE oci8_svcctx_initialize(int argc, VALUE *argv, VALUE self)
|
@@ -254,7 +292,7 @@ static VALUE oci8_svcctx_initialize(int argc, VALUE *argv, VALUE self)
|
|
254
292
|
svcctx->pid = getpid();
|
255
293
|
svcctx->is_autocommit = 0;
|
256
294
|
#ifdef RUBY_VM
|
257
|
-
svcctx->non_blocking =
|
295
|
+
svcctx->non_blocking = 1;
|
258
296
|
#endif
|
259
297
|
svcctx->long_read_len = INT2FIX(65535);
|
260
298
|
return Qnil;
|
@@ -265,13 +303,8 @@ static VALUE oci8_svcctx_initialize(int argc, VALUE *argv, VALUE self)
|
|
265
303
|
* call-seq:
|
266
304
|
* logoff
|
267
305
|
*
|
268
|
-
*
|
306
|
+
* Disconnects from the Oracle server. The uncommitted transaction is
|
269
307
|
* rollbacked.
|
270
|
-
*
|
271
|
-
* example:
|
272
|
-
* conn = OCI8.new("scott", "tiger")
|
273
|
-
* ... do something ...
|
274
|
-
* conn.logoff
|
275
308
|
*/
|
276
309
|
static VALUE oci8_svcctx_logoff(VALUE self)
|
277
310
|
{
|
@@ -312,7 +345,7 @@ static VALUE oci8_svcctx_logoff(VALUE self)
|
|
312
345
|
* call-seq:
|
313
346
|
* parse(sql_text) -> an instance of OCI8::Cursor
|
314
347
|
*
|
315
|
-
*
|
348
|
+
* Prepares the SQL statement and returns a new OCI8::Cursor.
|
316
349
|
*/
|
317
350
|
static VALUE oci8_svcctx_parse(VALUE self, VALUE sql)
|
318
351
|
{
|
@@ -328,13 +361,7 @@ static VALUE oci8_svcctx_parse(VALUE self, VALUE sql)
|
|
328
361
|
* call-seq:
|
329
362
|
* commit
|
330
363
|
*
|
331
|
-
*
|
332
|
-
*
|
333
|
-
* example:
|
334
|
-
* conn = OCI8.new("scott", "tiger")
|
335
|
-
* conn.exec("UPDATE emp SET sal = sal * 1.1") # yahoo
|
336
|
-
* conn.commit
|
337
|
-
* conn.logoff
|
364
|
+
* Commits the transaction.
|
338
365
|
*/
|
339
366
|
static VALUE oci8_commit(VALUE self)
|
340
367
|
{
|
@@ -347,13 +374,7 @@ static VALUE oci8_commit(VALUE self)
|
|
347
374
|
* call-seq:
|
348
375
|
* rollback
|
349
376
|
*
|
350
|
-
*
|
351
|
-
*
|
352
|
-
* example:
|
353
|
-
* conn = OCI8.new("scott", "tiger")
|
354
|
-
* conn.exec("UPDATE emp SET sal = sal * 0.9") # boos
|
355
|
-
* conn.rollback
|
356
|
-
* conn.logoff
|
377
|
+
* Rollbacks the transaction.
|
357
378
|
*/
|
358
379
|
static VALUE oci8_rollback(VALUE self)
|
359
380
|
{
|
@@ -366,8 +387,10 @@ static VALUE oci8_rollback(VALUE self)
|
|
366
387
|
* call-seq:
|
367
388
|
* non_blocking? -> true or false
|
368
389
|
*
|
369
|
-
*
|
370
|
-
*
|
390
|
+
* Returns +true+ if the connection is in non-blocking mode, +false+
|
391
|
+
* otherwise.
|
392
|
+
*
|
393
|
+
* See also #non_blocking=.
|
371
394
|
*/
|
372
395
|
static VALUE oci8_non_blocking_p(VALUE self)
|
373
396
|
{
|
@@ -389,20 +412,38 @@ static VALUE oci8_non_blocking_p(VALUE self)
|
|
389
412
|
* call-seq:
|
390
413
|
* non_blocking = true or false
|
391
414
|
*
|
392
|
-
*
|
393
|
-
*
|
415
|
+
* Sets +true+ to enable non-blocking mode, +false+ otherwise.
|
416
|
+
* The default setting depends on the ruby version and ruby-oci8
|
417
|
+
* version.
|
418
|
+
*
|
419
|
+
* When the connection is in blocking mode (non_blocking = false),
|
420
|
+
* SQL executions block not only the thread, but also the ruby
|
421
|
+
* process. It makes the whole application stop while a SQL execution
|
422
|
+
* needs long time.
|
423
|
+
*
|
424
|
+
* When in non-blocking mode (non_blocking = true), SQL executions
|
425
|
+
* block only the thread. It does't prevent other threads.
|
426
|
+
* A SQL execution which blocks a thread can be canceled by
|
427
|
+
* OCI8#break.
|
428
|
+
*
|
429
|
+
* === ruby 1.9
|
430
|
+
* The default setting is +true+ if the ruby-oci8 version is 2.0.3 or
|
431
|
+
* upper, +false+ otherwise.
|
432
|
+
*
|
433
|
+
* Ruby-oci8 makes the connection non-blocking by releasing ruby
|
434
|
+
* interpreter's GVL (Global VM Lock or Giant VM Lock) while OCI
|
435
|
+
* functions which may need more than one network round trips are in
|
436
|
+
* execution.
|
394
437
|
*
|
395
|
-
*
|
396
|
-
*
|
397
|
-
* not native one.
|
438
|
+
* === ruby 1.8
|
439
|
+
* The default setting is +false+.
|
398
440
|
*
|
399
|
-
*
|
400
|
-
*
|
401
|
-
*
|
402
|
-
*
|
441
|
+
* Ruby-oci8 makes the connection non-blocking by polling the return
|
442
|
+
* values of OCI functions. When an OCI function returns
|
443
|
+
* OCI_STILL_EXECUTING, the thread sleeps for 10 milli seconds to make
|
444
|
+
* a time for other threads to run. The sleep time is doubled up to
|
445
|
+
* 640 milli seconds as the function returns the same value.
|
403
446
|
*
|
404
|
-
* You can cancel an executing SQL by using OCI8#break from another thread.
|
405
|
-
* The canceled thread raises OCIBreak exception.
|
406
447
|
*/
|
407
448
|
static VALUE oci8_set_non_blocking(VALUE self, VALUE val)
|
408
449
|
{
|
@@ -428,8 +469,8 @@ static VALUE oci8_set_non_blocking(VALUE self, VALUE val)
|
|
428
469
|
* call-seq:
|
429
470
|
* autocommit? -> true or false
|
430
471
|
*
|
431
|
-
*
|
432
|
-
*
|
472
|
+
* Returns +true+ if the connection is in autocommit mode, +false+
|
473
|
+
* otherwise. The default value is +false+.
|
433
474
|
*/
|
434
475
|
static VALUE oci8_autocommit_p(VALUE self)
|
435
476
|
{
|
@@ -441,13 +482,7 @@ static VALUE oci8_autocommit_p(VALUE self)
|
|
441
482
|
* call-seq:
|
442
483
|
* autocommit = true or false
|
443
484
|
*
|
444
|
-
*
|
445
|
-
*
|
446
|
-
* example:
|
447
|
-
* conn = OCI8.new("scott", "tiger")
|
448
|
-
* conn.autocommit = true
|
449
|
-
* ... do something ...
|
450
|
-
* conn.logoff
|
485
|
+
* Sets the autocommit mode. The default value is +false+.
|
451
486
|
*/
|
452
487
|
static VALUE oci8_set_autocommit(VALUE self, VALUE val)
|
453
488
|
{
|
@@ -458,9 +493,15 @@ static VALUE oci8_set_autocommit(VALUE self, VALUE val)
|
|
458
493
|
|
459
494
|
/*
|
460
495
|
* call-seq:
|
461
|
-
* long_read_len ->
|
496
|
+
* long_read_len -> fixnum
|
497
|
+
*
|
498
|
+
* Gets the maximum length in bytes to fetch a LONG or LONG RAW
|
499
|
+
* column. The default value is 65535.
|
462
500
|
*
|
463
|
-
*
|
501
|
+
* If the actual data length is longer than long_read_len,
|
502
|
+
* "ORA-01406: fetched column value was truncated" is raised.
|
503
|
+
*
|
504
|
+
* Note: long_read_len is also used for XMLTYPE data type in 2.0.
|
464
505
|
*/
|
465
506
|
static VALUE oci8_long_read_len(VALUE self)
|
466
507
|
{
|
@@ -470,16 +511,13 @@ static VALUE oci8_long_read_len(VALUE self)
|
|
470
511
|
|
471
512
|
/*
|
472
513
|
* call-seq:
|
473
|
-
* long_read_len =
|
514
|
+
* long_read_len = fixnum
|
474
515
|
*
|
475
|
-
*
|
476
|
-
*
|
516
|
+
* Sets the maximum length in bytes to fetch a LONG or LONG RAW
|
517
|
+
* column.
|
518
|
+
*
|
519
|
+
* See also #long_read_len
|
477
520
|
*
|
478
|
-
* example:
|
479
|
-
* conn = OCI8.new('scott', 'tiger'
|
480
|
-
* conn.long_read_len = 1000000
|
481
|
-
* cursor = con.exec('select content from articles where id = :1', 23478)
|
482
|
-
* row = cursor.fetch
|
483
521
|
*/
|
484
522
|
static VALUE oci8_set_long_read_len(VALUE self, VALUE val)
|
485
523
|
{
|
@@ -493,8 +531,9 @@ static VALUE oci8_set_long_read_len(VALUE self, VALUE val)
|
|
493
531
|
* call-seq:
|
494
532
|
* break
|
495
533
|
*
|
496
|
-
*
|
497
|
-
*
|
534
|
+
* Cancels the executing SQL.
|
535
|
+
*
|
536
|
+
* See also #non_blocking=.
|
498
537
|
*/
|
499
538
|
static VALUE oci8_break(VALUE self)
|
500
539
|
{
|
@@ -517,10 +556,14 @@ static VALUE oci8_break(VALUE self)
|
|
517
556
|
|
518
557
|
/*
|
519
558
|
* call-seq:
|
520
|
-
* prefetch_rows =
|
559
|
+
* prefetch_rows = number
|
560
|
+
*
|
561
|
+
* Sets the prefetch rows size. The default value is one.
|
562
|
+
* When a select statement is executed, the OCI library allocate
|
563
|
+
* prefetch buffer to reduce the number of network round trips by
|
564
|
+
* retrieving specified number of rows in one round trip.
|
521
565
|
*
|
522
|
-
*
|
523
|
-
* when fetching multiple rows.
|
566
|
+
* Note: Active record adaptors set 100 by default.
|
524
567
|
*/
|
525
568
|
static VALUE oci8_set_prefetch_rows(VALUE self, VALUE val)
|
526
569
|
{
|
@@ -530,8 +573,13 @@ static VALUE oci8_set_prefetch_rows(VALUE self, VALUE val)
|
|
530
573
|
|
531
574
|
/*
|
532
575
|
* call-seq:
|
533
|
-
* oracle_server_vernum ->
|
576
|
+
* oracle_server_vernum -> an integer
|
534
577
|
*
|
578
|
+
* <b>(new in 2.0.1)</b>
|
579
|
+
*
|
580
|
+
* Returns a numerical format of the Oracle server version.
|
581
|
+
*
|
582
|
+
* See also: #oracle_server_version
|
535
583
|
*/
|
536
584
|
static VALUE oci8_oracle_server_vernum(VALUE self)
|
537
585
|
{
|
@@ -564,16 +612,20 @@ static VALUE oci8_oracle_server_vernum(VALUE self)
|
|
564
612
|
* call-seq:
|
565
613
|
* ping -> true or false
|
566
614
|
*
|
567
|
-
*
|
615
|
+
* <b>(new in 2.0.2)</b>
|
616
|
+
*
|
617
|
+
* Makes a round trip call to the server to confirm that the connection and
|
618
|
+
* the server are active.
|
568
619
|
*
|
569
620
|
* OCI8#ping also can be used to flush all the pending OCI client-side calls
|
570
|
-
* to the server if any exist.
|
621
|
+
* to the server if any exist.
|
571
622
|
*
|
572
|
-
*
|
573
|
-
* added OCI function
|
623
|
+
* === Oracle 10.2 client or upper
|
624
|
+
* A dummy round trip call is made by a newly added OCI function
|
625
|
+
* OCIPing[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci16msc007.htm#sthref3540] in Oracle 10.2.
|
574
626
|
*
|
575
|
-
*
|
576
|
-
* is executed to make a round trip call.
|
627
|
+
* === Oracle 10.1 client or lower
|
628
|
+
* A simple PL/SQL block "BEGIN NULL; END;" is executed to make a round trip call.
|
577
629
|
*/
|
578
630
|
static VALUE oci8_ping(VALUE self)
|
579
631
|
{
|
@@ -592,23 +644,36 @@ static VALUE oci8_ping(VALUE self)
|
|
592
644
|
|
593
645
|
/*
|
594
646
|
* call-seq:
|
595
|
-
* client_identifier = string
|
647
|
+
* client_identifier = string or nil
|
648
|
+
*
|
649
|
+
* <b>(new in 2.0.3)</b>
|
650
|
+
*
|
651
|
+
* Sets the client ID. This information is stored in the V$SESSION
|
652
|
+
* view.
|
653
|
+
*
|
654
|
+
* === Oracle 9i client or upper
|
655
|
+
*
|
656
|
+
* This doesn't perform network round trips. The change is reflected
|
657
|
+
* to the server by the next round trip such as OCI8#exec, OCI8#ping,
|
658
|
+
* etc.
|
659
|
+
*
|
660
|
+
* === Oracle 8i client or lower
|
596
661
|
*
|
597
|
-
*
|
598
|
-
*
|
662
|
+
* This executes the following PL/SQL block internally.
|
663
|
+
* The change is reflected immediately by a network round trip.
|
599
664
|
*
|
600
|
-
*
|
601
|
-
*
|
602
|
-
*
|
665
|
+
* BEGIN
|
666
|
+
* DBMS_SESSION.SET_IDENTIFIER(:client_id);
|
667
|
+
* END;
|
668
|
+
*
|
669
|
+
* See {Oracle Manual: Oracle Database PL/SQL Packages and Types Reference}[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sessio.htm#i996935]
|
603
670
|
*
|
604
|
-
* This call is equivalent to "DBMS_SESSION.SET_IDENTIFIER(client_id VARCHAR2);"
|
605
|
-
* and available when the server is Oracle 9i or upper.
|
606
671
|
*/
|
607
672
|
static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
|
608
673
|
{
|
609
|
-
OCISession *sess = oci8_get_oci_session(self);
|
610
674
|
char *ptr;
|
611
675
|
ub4 size;
|
676
|
+
int use_attr_set = 1;
|
612
677
|
|
613
678
|
if (!NIL_P(val)) {
|
614
679
|
OCI8SafeStringValue(val);
|
@@ -618,11 +683,19 @@ static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
|
|
618
683
|
ptr = "";
|
619
684
|
size = 0;
|
620
685
|
}
|
621
|
-
|
686
|
+
|
687
|
+
if (oracle_client_version < ORAVER_9_0) {
|
688
|
+
use_attr_set = 0;
|
689
|
+
} else if (oracle_client_version < ORAVERNUM(9, 2, 0, 3, 0) && size == 0) {
|
690
|
+
/* Workaround for Bug 2449486 */
|
691
|
+
use_attr_set = 0;
|
692
|
+
}
|
693
|
+
|
694
|
+
if (use_attr_set) {
|
622
695
|
if (size > 0 && ptr[0] == ':') {
|
623
696
|
rb_raise(rb_eArgError, "client identifier should not start with ':'.");
|
624
697
|
}
|
625
|
-
oci_lc(OCIAttrSet(
|
698
|
+
oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
|
626
699
|
size, OCI_ATTR_CLIENT_IDENTIFIER, oci8_errhp));
|
627
700
|
} else {
|
628
701
|
oci8_exec_sql_var_t bind_vars[1];
|
@@ -634,13 +707,225 @@ static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
|
|
634
707
|
bind_vars[0].indp = NULL;
|
635
708
|
bind_vars[0].alenp = NULL;
|
636
709
|
|
637
|
-
oci8_exec_sql(oci8_get_svcctx(self),
|
710
|
+
oci8_exec_sql(oci8_get_svcctx(self),
|
711
|
+
"BEGIN\n"
|
712
|
+
" DBMS_SESSION.SET_IDENTIFIER(:client_id);\n"
|
713
|
+
"END;\n", 0, NULL, 1, bind_vars, 1);
|
714
|
+
}
|
715
|
+
return val;
|
716
|
+
}
|
717
|
+
|
718
|
+
/*
|
719
|
+
* call-seq:
|
720
|
+
* module = string or nil
|
721
|
+
*
|
722
|
+
* <b>(new in 2.0.3)</b>
|
723
|
+
*
|
724
|
+
* Sets the name of the current module. This information is
|
725
|
+
* stored in the V$SESSION view and is also stored in the V$SQL view
|
726
|
+
* and the V$SQLAREA view when a SQL statement is executed and the SQL
|
727
|
+
* statement is first parsed in the Oracle server.
|
728
|
+
*
|
729
|
+
* === Oracle 10g client or upper
|
730
|
+
*
|
731
|
+
* This doesn't perform network round trips. The change is reflected
|
732
|
+
* to the server by the next round trip such as OCI8#exec, OCI8#ping,
|
733
|
+
* etc.
|
734
|
+
*
|
735
|
+
* === Oracle 9i client or lower
|
736
|
+
*
|
737
|
+
* This executes the following PL/SQL block internally.
|
738
|
+
* The change is reflected immediately by a network round trip.
|
739
|
+
*
|
740
|
+
* DECLARE
|
741
|
+
* action VARCHAR2(32);
|
742
|
+
* BEGIN
|
743
|
+
* -- retrieve action name.
|
744
|
+
* SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;
|
745
|
+
* -- change module name without modifying the action name.
|
746
|
+
* DBMS_APPLICATION_INFO.SET_MODULE(:module, action);
|
747
|
+
* END;
|
748
|
+
*
|
749
|
+
* See {Oracle Manual: Oracle Database PL/SQL Packages and Types Reference}[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_appinf.htm#i999254]
|
750
|
+
*
|
751
|
+
*/
|
752
|
+
static VALUE oci8_set_module(VALUE self, VALUE val)
|
753
|
+
{
|
754
|
+
char *ptr;
|
755
|
+
ub4 size;
|
756
|
+
|
757
|
+
if (!NIL_P(val)) {
|
758
|
+
OCI8SafeStringValue(val);
|
759
|
+
ptr = RSTRING_PTR(val);
|
760
|
+
size = RSTRING_LEN(val);
|
761
|
+
} else {
|
762
|
+
ptr = "";
|
763
|
+
size = 0;
|
764
|
+
}
|
765
|
+
if (oracle_client_version >= ORAVER_10_1) {
|
766
|
+
/* Oracle 10g or upper */
|
767
|
+
oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
|
768
|
+
size, OCI_ATTR_MODULE, oci8_errhp));
|
769
|
+
} else {
|
770
|
+
/* Oracle 9i or lower */
|
771
|
+
oci8_exec_sql_var_t bind_vars[1];
|
772
|
+
|
773
|
+
/* :module */
|
774
|
+
bind_vars[0].valuep = ptr;
|
775
|
+
bind_vars[0].value_sz = size;
|
776
|
+
bind_vars[0].dty = SQLT_CHR;
|
777
|
+
bind_vars[0].indp = NULL;
|
778
|
+
bind_vars[0].alenp = NULL;
|
779
|
+
|
780
|
+
oci8_exec_sql(oci8_get_svcctx(self),
|
781
|
+
"DECLARE\n"
|
782
|
+
" action VARCHAR2(32);\n"
|
783
|
+
"BEGIN\n"
|
784
|
+
" SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;\n"
|
785
|
+
" DBMS_APPLICATION_INFO.SET_MODULE(:module, action);\n"
|
786
|
+
"END;\n", 0, NULL, 1, bind_vars, 1);
|
787
|
+
}
|
788
|
+
return self;
|
789
|
+
}
|
790
|
+
|
791
|
+
/*
|
792
|
+
* call-seq:
|
793
|
+
* action = string or nil
|
794
|
+
*
|
795
|
+
* <b>(new in 2.0.3)</b>
|
796
|
+
*
|
797
|
+
* Sets the name of the current action within the current module.
|
798
|
+
* This information is stored in the V$SESSION view and is also
|
799
|
+
* stored in the V$SQL view and the V$SQLAREA view when a SQL
|
800
|
+
* statement is executed and the SQL statement is first parsed
|
801
|
+
* in the Oracle server.
|
802
|
+
*
|
803
|
+
* === Oracle 10g client or upper
|
804
|
+
*
|
805
|
+
* This doesn't perform network round trips. The change is reflected
|
806
|
+
* to the server by the next round trip such as OCI8#exec, OCI8#ping,
|
807
|
+
* etc.
|
808
|
+
*
|
809
|
+
* === Oracle 9i client or lower
|
810
|
+
*
|
811
|
+
* This executes the following PL/SQL block internally.
|
812
|
+
* The change is reflected immediately by a network round trip.
|
813
|
+
*
|
814
|
+
* BEGIN
|
815
|
+
* DBMS_APPLICATION_INFO.SET_ACTION(:action);
|
816
|
+
* END;
|
817
|
+
*
|
818
|
+
* See {Oracle Manual: Oracle Database PL/SQL Packages and Types Reference}[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_appinf.htm#i999254]
|
819
|
+
*
|
820
|
+
*/
|
821
|
+
static VALUE oci8_set_action(VALUE self, VALUE val)
|
822
|
+
{
|
823
|
+
char *ptr;
|
824
|
+
ub4 size;
|
825
|
+
|
826
|
+
if (!NIL_P(val)) {
|
827
|
+
OCI8SafeStringValue(val);
|
828
|
+
ptr = RSTRING_PTR(val);
|
829
|
+
size = RSTRING_LEN(val);
|
830
|
+
} else {
|
831
|
+
ptr = "";
|
832
|
+
size = 0;
|
833
|
+
}
|
834
|
+
if (oracle_client_version >= ORAVER_10_1) {
|
835
|
+
/* Oracle 10g or upper */
|
836
|
+
oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
|
837
|
+
size, OCI_ATTR_ACTION, oci8_errhp));
|
838
|
+
} else {
|
839
|
+
/* Oracle 9i or lower */
|
840
|
+
oci8_exec_sql_var_t bind_vars[1];
|
841
|
+
|
842
|
+
/* :action */
|
843
|
+
bind_vars[0].valuep = ptr;
|
844
|
+
bind_vars[0].value_sz = size;
|
845
|
+
bind_vars[0].dty = SQLT_CHR;
|
846
|
+
bind_vars[0].indp = NULL;
|
847
|
+
bind_vars[0].alenp = NULL;
|
848
|
+
|
849
|
+
oci8_exec_sql(oci8_get_svcctx(self),
|
850
|
+
"BEGIN\n"
|
851
|
+
" DBMS_APPLICATION_INFO.SET_ACTION(:action);\n"
|
852
|
+
"END;\n", 0, NULL, 1, bind_vars, 1);
|
853
|
+
}
|
854
|
+
return val;
|
855
|
+
}
|
856
|
+
|
857
|
+
/*
|
858
|
+
* call-seq:
|
859
|
+
* client_info = string or nil
|
860
|
+
*
|
861
|
+
* <b>(new in 2.0.3)</b>
|
862
|
+
*
|
863
|
+
* Sets additional information about the client application.
|
864
|
+
* This information is stored in the V$SESSION view.
|
865
|
+
*
|
866
|
+
* === Oracle 10g client or upper
|
867
|
+
*
|
868
|
+
* This doesn't perform network round trips. The change is reflected
|
869
|
+
* to the server by the next round trip such as OCI8#exec, OCI8#ping,
|
870
|
+
* etc.
|
871
|
+
*
|
872
|
+
* === Oracle 9i client or lower
|
873
|
+
*
|
874
|
+
* This executes the following PL/SQL block internally.
|
875
|
+
* The change is reflected immediately by a network round trip.
|
876
|
+
*
|
877
|
+
* BEGIN
|
878
|
+
* DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:client_info);
|
879
|
+
* END;
|
880
|
+
*
|
881
|
+
* See {Oracle Manual: Oracle Database PL/SQL Packages and Types Reference}[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_appinf.htm#CHEJCFGG]
|
882
|
+
*/
|
883
|
+
static VALUE oci8_set_client_info(VALUE self, VALUE val)
|
884
|
+
{
|
885
|
+
char *ptr;
|
886
|
+
ub4 size;
|
887
|
+
|
888
|
+
if (!NIL_P(val)) {
|
889
|
+
OCI8SafeStringValue(val);
|
890
|
+
ptr = RSTRING_PTR(val);
|
891
|
+
size = RSTRING_LEN(val);
|
892
|
+
} else {
|
893
|
+
ptr = "";
|
894
|
+
size = 0;
|
895
|
+
}
|
896
|
+
if (oracle_client_version >= ORAVER_10_1) {
|
897
|
+
/* Oracle 10g or upper */
|
898
|
+
oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
|
899
|
+
size, OCI_ATTR_CLIENT_INFO, oci8_errhp));
|
900
|
+
} else {
|
901
|
+
/* Oracle 9i or lower */
|
902
|
+
oci8_exec_sql_var_t bind_vars[1];
|
903
|
+
|
904
|
+
/* :client_info */
|
905
|
+
bind_vars[0].valuep = ptr;
|
906
|
+
bind_vars[0].value_sz = size;
|
907
|
+
bind_vars[0].dty = SQLT_CHR;
|
908
|
+
bind_vars[0].indp = NULL;
|
909
|
+
bind_vars[0].alenp = NULL;
|
910
|
+
|
911
|
+
oci8_exec_sql(oci8_get_svcctx(self),
|
912
|
+
"BEGIN\n"
|
913
|
+
" DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:client_info);\n"
|
914
|
+
"END;\n", 0, NULL, 1, bind_vars, 1);
|
638
915
|
}
|
639
916
|
return val;
|
640
917
|
}
|
641
918
|
|
642
919
|
VALUE Init_oci8(void)
|
643
920
|
{
|
921
|
+
#if 0
|
922
|
+
/*
|
923
|
+
* OCIHandle is the abstract base class for all OCI handles and
|
924
|
+
* descriptors which are opaque data types of Oracle Call Interface.
|
925
|
+
*/
|
926
|
+
oci8_cOCIHandle = rb_define_class("OCIHandle", rb_cObject);
|
927
|
+
cOCI8 = rb_define_class("OCI8", oci8_cOCIHandle);
|
928
|
+
#endif
|
644
929
|
cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_class);
|
645
930
|
|
646
931
|
oracle_client_vernum = INT2FIX(oracle_client_version);
|
@@ -674,6 +959,9 @@ VALUE Init_oci8(void)
|
|
674
959
|
rb_define_private_method(cOCI8, "oracle_server_vernum", oci8_oracle_server_vernum, 0);
|
675
960
|
rb_define_method(cOCI8, "ping", oci8_ping, 0);
|
676
961
|
rb_define_method(cOCI8, "client_identifier=", oci8_set_client_identifier, 1);
|
962
|
+
rb_define_method(cOCI8, "module=", oci8_set_module, 1);
|
963
|
+
rb_define_method(cOCI8, "action=", oci8_set_action, 1);
|
964
|
+
rb_define_method(cOCI8, "client_info=", oci8_set_client_info, 1);
|
677
965
|
return cOCI8;
|
678
966
|
}
|
679
967
|
|