ruby-oci8 2.1.7 → 2.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  * oci8.c - part of ruby-oci8
4
4
  *
5
- * Copyright (C) 2002-2013 KUBO Takehiro <kubo@jiubao.org>
5
+ * Copyright (C) 2002-2015 Kubo Takehiro <kubo@jiubao.org>
6
6
  *
7
7
  */
8
8
  #include "oci8.h"
@@ -30,6 +30,9 @@ extern rb_pid_t rb_w32_getpid(void);
30
30
  #ifndef OCI_ATTR_CLIENT_INFO
31
31
  #define OCI_ATTR_CLIENT_INFO 368
32
32
  #endif
33
+ #ifndef OCI_ATTR_TRANSACTION_IN_PROGRESS
34
+ #define OCI_ATTR_TRANSACTION_IN_PROGRESS 484
35
+ #endif
33
36
 
34
37
  #define OCI8_STATE_SESSION_BEGIN_WAS_CALLED 0x01
35
38
  #define OCI8_STATE_SERVER_ATTACH_WAS_CALLED 0x02
@@ -63,24 +66,106 @@ static VALUE dummy_env_method_missing(int argc, VALUE *argv, VALUE self)
63
66
  return rb_apply(obj, SYM2ID(method_id), args);
64
67
  }
65
68
 
66
- static void oci8_dont_free_handle_free(oci8_base_t *base)
69
+ static void oci8_handle_dont_free(oci8_base_t *base)
67
70
  {
68
71
  base->type = 0;
72
+ base->closed = 1;
69
73
  base->hp.ptr = NULL;
70
74
  }
71
75
 
72
- static oci8_base_vtable_t oci8_dont_free_handle_vtable = {
73
- NULL,
74
- oci8_dont_free_handle_free,
76
+ static const oci8_handle_data_type_t oci8_session_data_type = {
77
+ {
78
+ "OCI8::Session",
79
+ {
80
+ NULL,
81
+ oci8_handle_cleanup,
82
+ oci8_handle_size,
83
+ },
84
+ &oci8_handle_data_type.rb_data_type, NULL,
85
+ #ifdef RUBY_TYPED_WB_PROTECTED
86
+ RUBY_TYPED_WB_PROTECTED,
87
+ #endif
88
+ },
89
+ oci8_handle_dont_free,
90
+ sizeof(oci8_base_t),
91
+ };
92
+
93
+ static VALUE oci8_session_alloc(VALUE klass)
94
+ {
95
+ return oci8_allocate_typeddata(klass, &oci8_session_data_type);
96
+ }
97
+
98
+ static const oci8_handle_data_type_t oci8_server_data_type = {
99
+ {
100
+ "OCI8::Server",
101
+ {
102
+ NULL,
103
+ oci8_handle_cleanup,
104
+ oci8_handle_size,
105
+ },
106
+ &oci8_handle_data_type.rb_data_type, NULL,
107
+ #ifdef RUBY_TYPED_WB_PROTECTED
108
+ RUBY_TYPED_WB_PROTECTED,
109
+ #endif
110
+ },
111
+ oci8_handle_dont_free,
112
+ sizeof(oci8_base_t),
113
+ };
114
+
115
+ static VALUE oci8_server_alloc(VALUE klass)
116
+ {
117
+ return oci8_allocate_typeddata(klass, &oci8_server_data_type);
118
+ }
119
+
120
+ static const oci8_handle_data_type_t oci8_environment_data_type = {
121
+ {
122
+ "OCI8::Environment",
123
+ {
124
+ NULL,
125
+ oci8_handle_cleanup,
126
+ oci8_handle_size,
127
+ },
128
+ &oci8_handle_data_type.rb_data_type, NULL,
129
+ #ifdef RUBY_TYPED_WB_PROTECTED
130
+ RUBY_TYPED_WB_PROTECTED,
131
+ #endif
132
+ },
133
+ oci8_handle_dont_free,
134
+ sizeof(oci8_base_t),
135
+ };
136
+
137
+ static VALUE oci8_environment_alloc(VALUE klass)
138
+ {
139
+ return oci8_allocate_typeddata(klass, &oci8_environment_data_type);
140
+ }
141
+
142
+ static const oci8_handle_data_type_t oci8_process_data_type = {
143
+ {
144
+ "OCI8::Process",
145
+ {
146
+ NULL,
147
+ oci8_handle_cleanup,
148
+ oci8_handle_size,
149
+ },
150
+ &oci8_handle_data_type.rb_data_type, NULL,
151
+ #ifdef RUBY_TYPED_WB_PROTECTED
152
+ RUBY_TYPED_WB_PROTECTED,
153
+ #endif
154
+ },
155
+ oci8_handle_dont_free,
75
156
  sizeof(oci8_base_t),
76
157
  };
77
158
 
159
+ static VALUE oci8_process_alloc(VALUE klass)
160
+ {
161
+ return oci8_allocate_typeddata(klass, &oci8_process_data_type);
162
+ }
163
+
78
164
  static void copy_session_handle(oci8_svcctx_t *svcctx)
79
165
  {
80
166
  VALUE obj = rb_ivar_get(svcctx->base.self, id_at_session_handle);
81
- oci8_base_t *base;
167
+ oci8_base_t *base = oci8_check_typeddata(obj, &oci8_session_data_type, 1);
82
168
 
83
- Check_Handle(obj, cSession, base);
84
169
  base->type = OCI_HTYPE_SESSION;
85
170
  base->hp.usrhp = svcctx->usrhp;
86
171
  }
@@ -88,9 +173,8 @@ static void copy_session_handle(oci8_svcctx_t *svcctx)
88
173
  static void copy_server_handle(oci8_svcctx_t *svcctx)
89
174
  {
90
175
  VALUE obj = rb_ivar_get(svcctx->base.self, id_at_server_handle);
91
- oci8_base_t *base;
176
+ oci8_base_t *base = oci8_check_typeddata(obj, &oci8_server_data_type, 1);
92
177
 
93
- Check_Handle(obj, cServer, base);
94
178
  base->type = OCI_HTYPE_SERVER;
95
179
  base->hp.srvhp = svcctx->srvhp;
96
180
  }
@@ -115,6 +199,7 @@ static void oci8_svcctx_free(oci8_base_t *base)
115
199
  void *data = strategy->prepare(svcctx);
116
200
  int rv;
117
201
  svcctx->base.type = 0;
202
+ svcctx->base.closed = 1;
118
203
  svcctx->logoff_strategy = NULL;
119
204
  rv = oci8_run_native_thread(strategy->execute, data);
120
205
  if (rv != 0) {
@@ -127,22 +212,41 @@ static void oci8_svcctx_free(oci8_base_t *base)
127
212
  }
128
213
  }
129
214
  svcctx->base.type = 0;
215
+ svcctx->base.closed = 1;
130
216
  }
131
217
 
132
- static void oci8_svcctx_init(oci8_base_t *base)
218
+ static const oci8_handle_data_type_t oci8_svcctx_data_type = {
219
+ {
220
+ "OCI8",
221
+ {
222
+ NULL,
223
+ oci8_handle_cleanup,
224
+ oci8_handle_size,
225
+ },
226
+ &oci8_handle_data_type.rb_data_type, NULL,
227
+ #ifdef RUBY_TYPED_WB_PROTECTED
228
+ RUBY_TYPED_WB_PROTECTED,
229
+ #endif
230
+ },
231
+ oci8_svcctx_free,
232
+ sizeof(oci8_svcctx_t),
233
+ };
234
+
235
+ static VALUE oci8_svcctx_alloc(VALUE klass)
133
236
  {
134
- oci8_svcctx_t *svcctx = (oci8_svcctx_t *)base;
237
+ VALUE self = oci8_allocate_typeddata(klass, &oci8_svcctx_data_type);
238
+ oci8_svcctx_t *svcctx = (oci8_svcctx_t *)RTYPEDDATA_DATA(self);
135
239
  VALUE obj;
136
240
 
137
241
  svcctx->executing_thread = Qnil;
138
242
  /* set session handle */
139
243
  obj = rb_obj_alloc(cSession);
140
- rb_ivar_set(base->self, id_at_session_handle, obj);
141
- oci8_link_to_parent(DATA_PTR(obj), base);
244
+ rb_ivar_set(self, id_at_session_handle, obj);
245
+ oci8_link_to_parent(DATA_PTR(obj), &svcctx->base);
142
246
  /* set server handle */
143
247
  obj = rb_obj_alloc(cServer);
144
- rb_ivar_set(base->self, id_at_server_handle, obj);
145
- oci8_link_to_parent(DATA_PTR(obj), base);
248
+ rb_ivar_set(self, id_at_server_handle, obj);
249
+ oci8_link_to_parent(DATA_PTR(obj), &svcctx->base);
146
250
 
147
251
  svcctx->pid = getpid();
148
252
  svcctx->is_autocommit = 0;
@@ -150,29 +254,43 @@ static void oci8_svcctx_init(oci8_base_t *base)
150
254
  svcctx->non_blocking = 1;
151
255
  #endif
152
256
  svcctx->long_read_len = INT2FIX(65535);
257
+ return self;
153
258
  }
154
259
 
155
- static oci8_base_vtable_t oci8_svcctx_vtable = {
156
- NULL,
157
- oci8_svcctx_free,
158
- sizeof(oci8_svcctx_t),
159
- oci8_svcctx_init,
160
- };
161
-
162
260
  static VALUE oracle_client_vernum; /* Oracle client version number */
163
261
 
262
+ /*
263
+ * @overload oracle_client_vernum
264
+ *
265
+ * Returns Oracle client version as <i>Integer</i>.
266
+ * The Oracle version is encoded in 32-bit integer.
267
+ * It is devided into 5 parts: 8, 4, 8, 4 and 8 bits.
268
+ *
269
+ * @example
270
+ * # Oracle 9.2.0.4
271
+ * oracle_client_vernum # => 0x09200400
272
+ * # => 0x09 2 00 4 00
273
+ * # => 9.2.0.4.0
274
+ *
275
+ * # Oracle 11.1.0.7.0
276
+ * oracle_client_vernum # => 0x0b100700
277
+ * # => 0x0b 1 00 7 00
278
+ * # => 11.1.0.7.0
279
+ *
280
+ * @return [Integer]
281
+ * @private
282
+ */
164
283
  static VALUE oci8_s_oracle_client_vernum(VALUE klass)
165
284
  {
166
285
  return oracle_client_vernum;
167
286
  }
168
287
 
169
288
  /*
170
- * call-seq:
171
- * OCI8.__get_prop(key)
289
+ * @overload OCI8.__get_prop(key)
172
290
  *
173
- * @param [Fixnum] key 1 or 2
174
- *
175
- * @private
291
+ * @param [Fixnum] key 1, 2 or 3
292
+ * @return [Object] depends on +key+.
293
+ * @private
176
294
  */
177
295
  static VALUE oci8_s_get_prop(VALUE klass, VALUE key)
178
296
  {
@@ -188,16 +306,18 @@ static VALUE oci8_s_get_prop(VALUE klass, VALUE key)
188
306
 
189
307
 
190
308
  /*
191
- * call-seq:
192
- * OCI8.__set_prop(key, value)
309
+ * @overload OCI8.__set_prop(key, value)
193
310
  *
194
- * @param [Fixnum] key 1 or 2
195
- * @param [Object] value depends on +key+.
311
+ * @param [Fixnum] key 1, 2 or 3
312
+ * @param [Object] value depends on +key+.
196
313
  *
197
- * @private
314
+ * @private
198
315
  */
199
316
  static VALUE oci8_s_set_prop(VALUE klass, VALUE key, VALUE val)
200
317
  {
318
+ #ifdef HAVE_PLTHOOK
319
+ static int hook_functions_installed = 0;
320
+ #endif
201
321
  switch (NUM2INT(key)) {
202
322
  case 1:
203
323
  oci8_float_conversion_type_is_ruby = RTEST(val) ? 1 : 0;
@@ -212,6 +332,16 @@ static VALUE oci8_s_set_prop(VALUE klass, VALUE key, VALUE val)
212
332
  }
213
333
  oci8_env_mode = NUM2UINT(val);
214
334
  break;
335
+ case 3:
336
+ #ifdef HAVE_PLTHOOK
337
+ if (!hook_functions_installed) {
338
+ oci8_install_hook_functions();
339
+ hook_functions_installed = 1;
340
+ }
341
+ #else
342
+ rb_raise(rb_eNotImpError, ":cancel_read_at_exit isn't implemented on this machine.");
343
+ #endif
344
+ break;
215
345
  default:
216
346
  rb_raise(rb_eArgError, "Unknown prop %d", NUM2INT(key));
217
347
  }
@@ -219,23 +349,20 @@ static VALUE oci8_s_set_prop(VALUE klass, VALUE key, VALUE val)
219
349
  }
220
350
 
221
351
  /*
222
- * call-seq:
223
- * OCI8.error_message(message_no) -> string
352
+ * @overload error_message(message_no)
224
353
  *
225
- * Get the Oracle error message specified by message_no.
226
- * Its language depends on NLS_LANGUAGE.
354
+ * Get the Oracle error message specified by message_no.
355
+ * Its language depends on NLS_LANGUAGE.
227
356
  *
228
- * Note: This method is unavailable if the Oracle client version is 8.0.
357
+ * @example
358
+ * # When NLS_LANG is AMERICAN_AMERICA.AL32UTF8
359
+ * OCI8.error_message(1) # => "ORA-00001: unique constraint (%s.%s) violated"
229
360
  *
230
- * example:
231
- * # When NLS_LANG is AMERICAN_AMERICA.AL32UTF8
232
- * OCI8.error_message(1) # => "ORA-00001: unique constraint (%s.%s) violated"
233
- *
234
- * # When NLS_LANG is FRENCH_FRANCE.AL32UTF8
235
- * OCI8.error_message(1) # => "ORA-00001: violation de contrainte unique (%s.%s)"
361
+ * # When NLS_LANG is FRENCH_FRANCE.AL32UTF8
362
+ * OCI8.error_message(1) # => "ORA-00001: violation de contrainte unique (%s.%s)"
236
363
  *
237
- * @param [Fixnum] message_no Oracle error message number
238
- * @return [String] Oracle error message
364
+ * @param [Fixnum] message_no Oracle error message number
365
+ * @return [String] Oracle error message
239
366
  */
240
367
  static VALUE oci8_s_error_message(VALUE klass, VALUE msgid)
241
368
  {
@@ -270,17 +397,18 @@ void oci8_do_parse_connect_string(VALUE conn_str, VALUE *user, VALUE *pass, VALU
270
397
  }
271
398
 
272
399
  /*
273
- * call-seq:
274
- * parse_connect_string(string) -> [username, password, dbname, privilege]
400
+ * @overload parse_connect_string(connect_string)
275
401
  *
276
- * Extracts +username+, +password+, +dbname+ and +privilege+ from the specified +string+.
402
+ * Extracts +username+, +password+, +dbname+ and +privilege+ from +connect_string+.
277
403
  *
278
- * example:
279
- * "scott/tiger" -> ["scott", "tiger", nil, nil],
280
- * "scott/tiger@oradb.example.com" -> ["scott", "tiger", "oradb.example.com", nil]
281
- * "sys/change_on_install as sysdba" -> ["sys", "change_on_install", nil, :SYSDBA]
404
+ * @example
405
+ * "scott/tiger" -> ["scott", "tiger", nil, nil],
406
+ * "scott/tiger@oradb.example.com" -> ["scott", "tiger", "oradb.example.com", nil]
407
+ * "sys/change_on_install as sysdba" -> ["sys", "change_on_install", nil, :SYSDBA]
282
408
  *
283
- * @private
409
+ * @param [String] connect_string
410
+ * @return [Array] [username, password, dbname]
411
+ * @private
284
412
  */
285
413
  static VALUE oci8_parse_connect_string(VALUE self, VALUE conn_str)
286
414
  {
@@ -317,9 +445,15 @@ static void *simple_logoff_execute(void *arg)
317
445
  {
318
446
  simple_logoff_arg_t *sla = (simple_logoff_arg_t *)arg;
319
447
  OCIError *errhp = oci8_errhp;
448
+ boolean txn = TRUE;
320
449
  sword rv;
321
450
 
322
- OCITransRollback(sla->svchp, errhp, OCI_DEFAULT);
451
+ if (oracle_client_version >= ORAVER_12_1) {
452
+ OCIAttrGet(sla->usrhp, OCI_HTYPE_SESSION, &txn, NULL, OCI_ATTR_TRANSACTION_IN_PROGRESS, errhp);
453
+ }
454
+ if (txn) {
455
+ OCITransRollback(sla->svchp, errhp, OCI_DEFAULT);
456
+ }
323
457
  rv = OCILogoff(sla->svchp, errhp);
324
458
  xfree(sla);
325
459
  return (void*)(VALUE)rv;
@@ -358,9 +492,15 @@ static void *complex_logoff_execute(void *arg)
358
492
  {
359
493
  complex_logoff_arg_t *cla = (complex_logoff_arg_t *)arg;
360
494
  OCIError *errhp = oci8_errhp;
495
+ boolean txn = TRUE;
361
496
  sword rv = OCI_SUCCESS;
362
497
 
363
- OCITransRollback(cla->svchp, errhp, OCI_DEFAULT);
498
+ if (oracle_client_version >= ORAVER_12_1) {
499
+ OCIAttrGet(cla->usrhp, OCI_HTYPE_SESSION, &txn, NULL, OCI_ATTR_TRANSACTION_IN_PROGRESS, errhp);
500
+ }
501
+ if (txn) {
502
+ OCITransRollback(cla->svchp, errhp, OCI_DEFAULT);
503
+ }
364
504
 
365
505
  if (cla->state & OCI8_STATE_SESSION_BEGIN_WAS_CALLED) {
366
506
  rv = OCISessionEnd(cla->svchp, oci8_errhp, cla->usrhp, OCI_DEFAULT);
@@ -389,16 +529,19 @@ static const oci8_logoff_strategy_t complex_logoff = {
389
529
  };
390
530
 
391
531
  /*
392
- * call-seq:
393
- * logon2(username, password, dbname, mode) -> connection
532
+ * @overload logon2(username, password, dbname, mode)
394
533
  *
395
- * Creates a simple logon session by the OCI function OCILogon2().
534
+ * Creates a simple logon session by the OCI function OCILogon2().
396
535
  *
397
- * @private
536
+ * @param [String] username
537
+ * @param [String] password
538
+ * @param [String] dbname
539
+ * @param [Integer] mode
540
+ * @private
398
541
  */
399
542
  static VALUE oci8_logon2(VALUE self, VALUE username, VALUE password, VALUE dbname, VALUE mode)
400
543
  {
401
- oci8_svcctx_t *svcctx = DATA_PTR(self);
544
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
402
545
  ub4 logon2_mode;
403
546
 
404
547
  if (svcctx->logoff_strategy != NULL) {
@@ -441,17 +584,16 @@ static VALUE oci8_logon2(VALUE self, VALUE username, VALUE password, VALUE dbnam
441
584
  }
442
585
 
443
586
  /*
444
- * call-seq:
445
- * allocate_handles()
587
+ * @overload allocate_handles()
446
588
  *
447
- * Allocates a service context handle, a session handle and a
448
- * server handle to use explicit attach and begin-session calls.
589
+ * Allocates a service context handle, a session handle and a
590
+ * server handle to use explicit attach and begin-session calls.
449
591
  *
450
- * @private
592
+ * @private
451
593
  */
452
594
  static VALUE oci8_allocate_handles(VALUE self)
453
595
  {
454
- oci8_svcctx_t *svcctx = DATA_PTR(self);
596
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
455
597
  sword rv;
456
598
 
457
599
  if (svcctx->logoff_strategy != NULL) {
@@ -481,12 +623,13 @@ static VALUE oci8_allocate_handles(VALUE self)
481
623
  }
482
624
 
483
625
  /*
484
- * call-seq:
485
- * server_attach(dbname, mode)
626
+ * @overload server_attach(dbname, mode)
486
627
  *
487
- * Attachs to the server by the OCI function OCIServerAttach().
628
+ * Attachs to the server by the OCI function OCIServerAttach().
488
629
  *
489
- * @private
630
+ * @param [String] dbname
631
+ * @param [Integer] mode
632
+ * @private
490
633
  */
491
634
  static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode)
492
635
  {
@@ -523,16 +666,17 @@ static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode)
523
666
  }
524
667
 
525
668
  /*
526
- * call-seq:
527
- * session_begin(cred, mode)
669
+ * @overload session_begin(cred, mode)
528
670
  *
529
- * Begins the session by the OCI function OCISessionBegin().
671
+ * Begins the session by the OCI function OCISessionBegin().
530
672
  *
531
- * @private
673
+ * @param [Fixnum] cred
674
+ * @param [Fixnum] mode
675
+ * @private
532
676
  */
533
677
  static VALUE oci8_session_begin(VALUE self, VALUE cred, VALUE mode)
534
678
  {
535
- oci8_svcctx_t *svcctx = DATA_PTR(self);
679
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
536
680
 
537
681
  if (svcctx->logoff_strategy != &complex_logoff) {
538
682
  rb_raise(rb_eRuntimeError, "Use this method only for the service context handle created by OCI8#server_handle().");
@@ -559,15 +703,14 @@ static VALUE oci8_session_begin(VALUE self, VALUE cred, VALUE mode)
559
703
  }
560
704
 
561
705
  /*
562
- * call-seq:
563
- * logoff
706
+ * @overload logoff
564
707
  *
565
- * Disconnects from the Oracle server. The uncommitted transaction is
566
- * rollbacked.
708
+ * Disconnects from the Oracle server. The uncommitted transaction is
709
+ * rollbacked.
567
710
  */
568
711
  static VALUE oci8_svcctx_logoff(VALUE self)
569
712
  {
570
- oci8_svcctx_t *svcctx = (oci8_svcctx_t *)DATA_PTR(self);
713
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
571
714
 
572
715
  while (svcctx->base.children != NULL) {
573
716
  oci8_base_free(svcctx->base.children);
@@ -576,6 +719,7 @@ static VALUE oci8_svcctx_logoff(VALUE self)
576
719
  const oci8_logoff_strategy_t *strategy = svcctx->logoff_strategy;
577
720
  void *data = strategy->prepare(svcctx);
578
721
  svcctx->base.type = 0;
722
+ svcctx->base.closed = 1;
579
723
  svcctx->logoff_strategy = NULL;
580
724
  chker2(oci8_call_without_gvl(svcctx, strategy->execute, data), &svcctx->base);
581
725
  }
@@ -583,43 +727,40 @@ static VALUE oci8_svcctx_logoff(VALUE self)
583
727
  }
584
728
 
585
729
  /*
586
- * call-seq:
587
- * commit
730
+ * @overload commit
588
731
  *
589
- * Commits the transaction.
732
+ * Commits the transaction.
590
733
  */
591
734
  static VALUE oci8_commit(VALUE self)
592
735
  {
593
- oci8_svcctx_t *svcctx = DATA_PTR(self);
736
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
594
737
  chker2(OCITransCommit_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT), &svcctx->base);
595
738
  return self;
596
739
  }
597
740
 
598
741
  /*
599
- * call-seq:
600
- * rollback
742
+ * @overload rollback
601
743
  *
602
- * Rollbacks the transaction.
744
+ * Rollbacks the transaction.
603
745
  */
604
746
  static VALUE oci8_rollback(VALUE self)
605
747
  {
606
- oci8_svcctx_t *svcctx = DATA_PTR(self);
748
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
607
749
  chker2(OCITransRollback_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT), &svcctx->base);
608
750
  return self;
609
751
  }
610
752
 
611
753
  /*
612
- * call-seq:
613
- * non_blocking? -> true or false
754
+ * @overload non_blocking?
614
755
  *
615
- * Returns +true+ if the connection is in non-blocking mode, +false+
616
- * otherwise.
756
+ * Returns +true+ if the connection is in non-blocking mode, +false+
757
+ * otherwise.
617
758
  *
618
- * See also #non_blocking=.
759
+ * @see #non_blocking=
619
760
  */
620
761
  static VALUE oci8_non_blocking_p(VALUE self)
621
762
  {
622
- oci8_svcctx_t *svcctx = DATA_PTR(self);
763
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
623
764
  #ifdef NATIVE_THREAD_WITH_GVL
624
765
  return svcctx->non_blocking ? Qtrue : Qfalse;
625
766
  #else
@@ -631,45 +772,25 @@ static VALUE oci8_non_blocking_p(VALUE self)
631
772
  }
632
773
 
633
774
  /*
634
- * call-seq:
635
- * non_blocking = true or false
636
- *
637
- * Sets +true+ to enable non-blocking mode, +false+ otherwise.
638
- * The default setting depends on the ruby version and ruby-oci8
639
- * version.
775
+ * @overload non_blocking=(non_blocking_mode)
640
776
  *
641
- * When the connection is in blocking mode (non_blocking = false),
642
- * SQL executions block not only the thread, but also the ruby
643
- * process. It makes the whole application stop while a SQL execution
644
- * needs long time.
777
+ * Sets +true+ to enable non-blocking mode, +false+ otherwise.
778
+ * The default value is +true+ except ruby 1.8.
645
779
  *
646
- * When in non-blocking mode (non_blocking = true), SQL executions
647
- * block only the thread. It does't prevent other threads.
648
- * A SQL execution which blocks a thread can be canceled by
649
- * OCI8#break.
780
+ * When the connection is in non-blocking mode (non_blocking = true),
781
+ * an SQL execution blocks the thread running the SQL.
782
+ * It does't prevent other threads. The blocking thread can be canceled
783
+ * by {OCI8#break}.
650
784
  *
651
- * === ruby 1.9
652
- * The default setting is +true+ if the ruby-oci8 version is 2.0.3 or
653
- * upper, +false+ otherwise.
654
- *
655
- * Ruby-oci8 makes the connection non-blocking by releasing ruby
656
- * interpreter's GVL (Global VM Lock or Giant VM Lock) while OCI
657
- * functions which may need more than one network round trips are in
658
- * execution.
659
- *
660
- * === ruby 1.8
661
- * The default setting is +false+.
662
- *
663
- * Ruby-oci8 makes the connection non-blocking by polling the return
664
- * values of OCI functions. When an OCI function returns
665
- * OCI_STILL_EXECUTING, the thread sleeps for 10 milli seconds to make
666
- * a time for other threads to run. The sleep time is doubled up to
667
- * 640 milli seconds as the function returns the same value.
785
+ * When in blocking mode (non_blocking = false), an SQL execution blocks
786
+ * not only the thread, but also the ruby process itself. It makes the
787
+ * whole application stop until the SQL finishes.
668
788
  *
789
+ * @param [Boolean] non_blocking_mode
669
790
  */
670
791
  static VALUE oci8_set_non_blocking(VALUE self, VALUE val)
671
792
  {
672
- oci8_svcctx_t *svcctx = DATA_PTR(self);
793
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
673
794
  #ifdef NATIVE_THREAD_WITH_GVL
674
795
  svcctx->non_blocking = RTEST(val);
675
796
  #else
@@ -688,78 +809,87 @@ static VALUE oci8_set_non_blocking(VALUE self, VALUE val)
688
809
  }
689
810
 
690
811
  /*
691
- * call-seq:
692
- * autocommit? -> true or false
812
+ * @overload autocommit?
693
813
  *
694
- * Returns +true+ if the connection is in autocommit mode, +false+
695
- * otherwise. The default value is +false+.
814
+ * Returns +true+ if the connection is in autocommit mode, +false+
815
+ * otherwise. The default value is +false+.
696
816
  */
697
817
  static VALUE oci8_autocommit_p(VALUE self)
698
818
  {
699
- oci8_svcctx_t *svcctx = DATA_PTR(self);
819
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
700
820
  return svcctx->is_autocommit ? Qtrue : Qfalse;
701
821
  }
702
822
 
703
823
  /*
704
- * call-seq:
705
- * autocommit = true or false
824
+ * @overload autocommit=(autocommit_mode)
706
825
  *
707
- * Sets the autocommit mode. The default value is +false+.
826
+ * Sets the autocommit mode. The default value is +false+.
827
+ *
828
+ * @param [Boolean] autocommit_mode
708
829
  */
709
830
  static VALUE oci8_set_autocommit(VALUE self, VALUE val)
710
831
  {
711
- oci8_svcctx_t *svcctx = DATA_PTR(self);
832
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
712
833
  svcctx->is_autocommit = RTEST(val);
713
834
  return val;
714
835
  }
715
836
 
716
837
  /*
717
- * call-seq:
718
- * long_read_len -> fixnum
838
+ * @overload long_read_len
839
+ *
840
+ * Gets the maximum length in bytes to fetch a LONG or LONG RAW
841
+ * column. The default value is 65535.
719
842
  *
720
- * Gets the maximum length in bytes to fetch a LONG or LONG RAW
721
- * column. The default value is 65535.
843
+ * If the actual data length is longer than long_read_len,
844
+ * the fetched valud is truncated and the value of {OCI8#last_error}
845
+ * become {OCISuccessWithInfo} whose message is "ORA-01406: fetched column value was truncated".
722
846
  *
723
- * If the actual data length is longer than long_read_len,
724
- * "ORA-01406: fetched column value was truncated" is raised.
847
+ * Note: long_read_len is also used for maximum length of XMLTYPE data type.
725
848
  *
726
- * Note: long_read_len is also used for XMLTYPE data type in 2.0.
849
+ * @return [Integer]
850
+ * @see #long_read_len=
727
851
  */
728
852
  static VALUE oci8_long_read_len(VALUE self)
729
853
  {
730
- oci8_svcctx_t *svcctx = DATA_PTR(self);
854
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
731
855
  return svcctx->long_read_len;
732
856
  }
733
857
 
734
858
  /*
735
- * call-seq:
736
- * long_read_len = fixnum
737
- *
738
- * Sets the maximum length in bytes to fetch a LONG or LONG RAW
739
- * column.
859
+ * @overload long_read_len=(length)
740
860
  *
741
- * See also #long_read_len
861
+ * Sets the maximum length in bytes to fetch a LONG or LONG RAW
862
+ * column.
742
863
  *
864
+ * @param [Integer] length
865
+ * @see #long_read_len
743
866
  */
744
867
  static VALUE oci8_set_long_read_len(VALUE self, VALUE val)
745
868
  {
746
- oci8_svcctx_t *svcctx = DATA_PTR(self);
869
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
747
870
  Check_Type(val, T_FIXNUM);
748
- svcctx->long_read_len = val;
871
+ RB_OBJ_WRITE(self, &svcctx->long_read_len, val);
749
872
  return val;
750
873
  }
751
874
 
752
875
  /*
753
- * call-seq:
754
- * break
876
+ * @overload break
877
+ *
878
+ * Cancels the executing SQL.
879
+ *
880
+ * Note that this doesn't work when the following cases.
755
881
  *
756
- * Cancels the executing SQL.
882
+ * * The Oracle server runs on Windows.
883
+ * * {Out-of-band data}[http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Out-of-band_data] are blocked by a firewall or by a VPN.
757
884
  *
758
- * See also #non_blocking=.
885
+ * In the latter case, create an sqlnet.ora file in the path specified
886
+ * by the TNS_ADMIN environment variable that sets {DISABLE_OOB=on}[http://www.orafaq.com/wiki/SQL*Net_FAQ#What_are_inband_and_out_of_band_breaks.3F].
887
+ *
888
+ * @see OCI8#non_blocking=
759
889
  */
760
890
  static VALUE oci8_break(VALUE self)
761
891
  {
762
- oci8_svcctx_t *svcctx = DATA_PTR(self);
892
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
763
893
 
764
894
  if (NIL_P(svcctx->executing_thread)) {
765
895
  return Qfalse;
@@ -772,18 +902,18 @@ static VALUE oci8_break(VALUE self)
772
902
  }
773
903
 
774
904
  /*
775
- * call-seq:
776
- * oracle_server_vernum -> an integer
905
+ * @overload oracle_server_vernum
777
906
  *
778
- * Returns a numerical format of the Oracle server version.
907
+ * Returns a numerical format of the Oracle server version.
779
908
  *
780
- * @see OCI8#oracle_server_version
781
- * @since 2.0.1
782
- * @private
909
+ * @return [Integer]
910
+ * @see OCI8#oracle_server_version
911
+ * @since 2.0.1
912
+ * @private
783
913
  */
784
914
  static VALUE oci8_oracle_server_vernum(VALUE self)
785
915
  {
786
- oci8_svcctx_t *svcctx = DATA_PTR(self);
916
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
787
917
  char buf[100];
788
918
  ub4 version;
789
919
 
@@ -792,23 +922,23 @@ static VALUE oci8_oracle_server_vernum(VALUE self)
792
922
  }
793
923
 
794
924
  /*
795
- * call-seq:
796
- * ping -> true or false
925
+ * @overload ping
797
926
  *
798
- * Makes a round trip call to the server to confirm that the connection and
799
- * the server are active.
927
+ * Makes a round trip call to the server to confirm that the connection and
928
+ * the server are active.
800
929
  *
801
- * OCI8#ping also can be used to flush all the pending OCI client-side calls
802
- * to the server if any exist.
930
+ * This also flushes all the pending OCI client-side calls such as {OCI8#action=},
931
+ * {OCI8#client_identifier=}, {OCI8#client_info=} and {OCI8#module=}.
803
932
  *
804
- * === Oracle 10.2 client or upper
805
- * A dummy round trip call is made by a newly added OCI function
806
- * OCIPing[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci16msc007.htm#sthref3540] in Oracle 10.2.
933
+ * === Oracle 10.2 client or upper
934
+ * A dummy round trip call is made by the OCI function
935
+ * OCIPing[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci16msc007.htm#sthref3540] added in Oracle 10.2.
807
936
  *
808
- * === Oracle 10.1 client or lower
809
- * A simple PL/SQL block "BEGIN NULL; END;" is executed to make a round trip call.
937
+ * === Oracle 10.1 client or lower
938
+ * A simple PL/SQL block "BEGIN NULL; END;" is executed to make a round trip call.
810
939
  *
811
- * @since 2.0.2
940
+ * @return [Boolean]
941
+ * @since 2.0.2
812
942
  */
813
943
  static VALUE oci8_ping(VALUE self)
814
944
  {
@@ -826,33 +956,31 @@ static VALUE oci8_ping(VALUE self)
826
956
  }
827
957
 
828
958
  /*
829
- * call-seq:
830
- * client_identifier = string or nil
959
+ * @overload client_identifier=(client_identifier)
831
960
  *
832
- * Sets the client ID. This information is stored in the V$SESSION
833
- * view.
961
+ * Sets the specified value to {V$SESSION.CLIENT_IDENTIFIER}[http://docs.oracle.com/database/121/REFRN/refrn30223.htm#r62c1-t21].
834
962
  *
835
- * === Oracle 9i client or upper
963
+ * === Oracle 9i client or upper
836
964
  *
837
- * This doesn't perform network round trips. The change is reflected
838
- * to the server by the next round trip such as OCI8#exec, OCI8#ping,
839
- * etc.
965
+ * The specified value is sent to the server by piggybacking on the next network
966
+ * round trip issued by {OCI8#exec}, {OCI8#ping} and so on.
840
967
  *
841
- * === Oracle 8i client or lower
968
+ * === Oracle 8i client or lower
842
969
  *
843
- * This executes the following PL/SQL block internally.
844
- * The change is reflected immediately by a network round trip.
970
+ * This executes the following PL/SQL block internally.
845
971
  *
846
- * BEGIN
847
- * DBMS_SESSION.SET_IDENTIFIER(:client_id);
848
- * END;
972
+ * BEGIN
973
+ * DBMS_SESSION.SET_IDENTIFIER(:client_id);
974
+ * END;
849
975
  *
850
- * 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]
976
+ * 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]
851
977
  *
852
- * @since 2.0.3
978
+ * @param [String] client_identifier
979
+ * @since 2.0.3
853
980
  */
854
981
  static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
855
982
  {
983
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
856
984
  const char *ptr;
857
985
  ub4 size;
858
986
 
@@ -869,9 +997,9 @@ static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
869
997
  if (size > 0 && ptr[0] == ':') {
870
998
  rb_raise(rb_eArgError, "client identifier should not start with ':'.");
871
999
  }
872
- chker2(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, (dvoid*)ptr,
1000
+ chker2(OCIAttrSet(svcctx->usrhp, OCI_HTYPE_SESSION, (dvoid*)ptr,
873
1001
  size, OCI_ATTR_CLIENT_IDENTIFIER, oci8_errhp),
874
- DATA_PTR(self));
1002
+ &svcctx->base);
875
1003
  } else {
876
1004
  /* Workaround for Bug 2449486 */
877
1005
  oci8_exec_sql_var_t bind_vars[1];
@@ -883,7 +1011,7 @@ static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
883
1011
  bind_vars[0].indp = NULL;
884
1012
  bind_vars[0].alenp = NULL;
885
1013
 
886
- oci8_exec_sql(oci8_get_svcctx(self),
1014
+ oci8_exec_sql(svcctx,
887
1015
  "BEGIN\n"
888
1016
  " DBMS_SESSION.SET_IDENTIFIER(:client_id);\n"
889
1017
  "END;\n", 0, NULL, 1, bind_vars, 1);
@@ -892,40 +1020,39 @@ static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
892
1020
  }
893
1021
 
894
1022
  /*
895
- * call-seq:
896
- * module = string or nil
1023
+ * @overload module=(module)
897
1024
  *
898
- * Sets the name of the current module. This information is
899
- * stored in the V$SESSION view and is also stored in the V$SQL view
900
- * and the V$SQLAREA view when a SQL statement is executed and the SQL
901
- * statement is first parsed in the Oracle server.
1025
+ * Sets the specified value to {V$SESSION.MODULE}[http://docs.oracle.com/database/121/REFRN/refrn30223.htm#r40c1-t21].
1026
+ * This is also stored in {V$SQL.MODULE}[http://docs.oracle.com/database/121/REFRN/refrn30246.htm#r49c1-t58]
1027
+ * and {V$SQLAREA.MODULE}[http://docs.oracle.com/database/121/REFRN/refrn30259.htm#r46c1-t94]
1028
+ * when an SQL statement is first parsed in the Oracle server.
902
1029
  *
903
- * === Oracle 10g client or upper
1030
+ * === Oracle 10g client or upper
904
1031
  *
905
- * This doesn't perform network round trips. The change is reflected
906
- * to the server by the next round trip such as OCI8#exec, OCI8#ping,
907
- * etc.
1032
+ * The specified value is sent to the server by piggybacking on the next network
1033
+ * round trip issued by {OCI8#exec}, {OCI8#ping} and so on.
908
1034
  *
909
- * === Oracle 9i client or lower
1035
+ * === Oracle 9i client or lower
910
1036
  *
911
- * This executes the following PL/SQL block internally.
912
- * The change is reflected immediately by a network round trip.
1037
+ * This executes the following PL/SQL block internally.
913
1038
  *
914
- * DECLARE
915
- * action VARCHAR2(32);
916
- * BEGIN
917
- * -- retrieve action name.
918
- * SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;
919
- * -- change module name without modifying the action name.
920
- * DBMS_APPLICATION_INFO.SET_MODULE(:module, action);
921
- * END;
1039
+ * DECLARE
1040
+ * action VARCHAR2(32);
1041
+ * BEGIN
1042
+ * -- retrieve action name.
1043
+ * SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;
1044
+ * -- change module name without modifying the action name.
1045
+ * DBMS_APPLICATION_INFO.SET_MODULE(:module, action);
1046
+ * END;
922
1047
  *
923
- * 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]
1048
+ * 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]
924
1049
  *
925
- * @since 2.0.3
1050
+ * @param [String] module
1051
+ * @since 2.0.3
926
1052
  */
927
1053
  static VALUE oci8_set_module(VALUE self, VALUE val)
928
1054
  {
1055
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
929
1056
  const char *ptr;
930
1057
  ub4 size;
931
1058
 
@@ -939,9 +1066,9 @@ static VALUE oci8_set_module(VALUE self, VALUE val)
939
1066
  }
940
1067
  if (oracle_client_version >= ORAVER_10_1) {
941
1068
  /* Oracle 10g or upper */
942
- chker2(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, (dvoid*)ptr,
1069
+ chker2(OCIAttrSet(svcctx->usrhp, OCI_HTYPE_SESSION, (dvoid*)ptr,
943
1070
  size, OCI_ATTR_MODULE, oci8_errhp),
944
- DATA_PTR(self));
1071
+ &svcctx->base);
945
1072
  } else {
946
1073
  /* Oracle 9i or lower */
947
1074
  oci8_exec_sql_var_t bind_vars[1];
@@ -953,7 +1080,7 @@ static VALUE oci8_set_module(VALUE self, VALUE val)
953
1080
  bind_vars[0].indp = NULL;
954
1081
  bind_vars[0].alenp = NULL;
955
1082
 
956
- oci8_exec_sql(oci8_get_svcctx(self),
1083
+ oci8_exec_sql(svcctx,
957
1084
  "DECLARE\n"
958
1085
  " action VARCHAR2(32);\n"
959
1086
  "BEGIN\n"
@@ -965,36 +1092,34 @@ static VALUE oci8_set_module(VALUE self, VALUE val)
965
1092
  }
966
1093
 
967
1094
  /*
968
- * call-seq:
969
- * action = string or nil
1095
+ * @overload action=(action)
970
1096
  *
971
- * Sets the name of the current action within the current module.
972
- * This information is stored in the V$SESSION view and is also
973
- * stored in the V$SQL view and the V$SQLAREA view when a SQL
974
- * statement is executed and the SQL statement is first parsed
975
- * in the Oracle server.
1097
+ * Sets the specified value to {V$SESSION.ACTION}[http://docs.oracle.com/database/121/REFRN/refrn30223.htm#r42c1-t21].
1098
+ * This is also stored in {V$SQL.ACTION}[http://docs.oracle.com/database/121/REFRN/refrn30246.htm#r51c1-t58]
1099
+ * and {V$SQLAREA.ACTION}[http://docs.oracle.com/database/121/REFRN/refrn30259.htm#r48c1-t94]
1100
+ * when an SQL statement is first parsed in the Oracle server.
976
1101
  *
977
- * === Oracle 10g client or upper
1102
+ * === Oracle 10g client or upper
978
1103
  *
979
- * This doesn't perform network round trips. The change is reflected
980
- * to the server by the next round trip such as OCI8#exec, OCI8#ping,
981
- * etc.
1104
+ * The specified value is sent to the server by piggybacking on the next network
1105
+ * round trip issued by {OCI8#exec}, {OCI8#ping} and so on.
982
1106
  *
983
- * === Oracle 9i client or lower
1107
+ * === Oracle 9i client or lower
984
1108
  *
985
- * This executes the following PL/SQL block internally.
986
- * The change is reflected immediately by a network round trip.
1109
+ * This executes the following PL/SQL block internally.
987
1110
  *
988
- * BEGIN
989
- * DBMS_APPLICATION_INFO.SET_ACTION(:action);
990
- * END;
1111
+ * BEGIN
1112
+ * DBMS_APPLICATION_INFO.SET_ACTION(:action);
1113
+ * END;
991
1114
  *
992
- * 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]
1115
+ * 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]
993
1116
  *
994
- * @since 2.0.3
1117
+ * @param [String] action
1118
+ * @since 2.0.3
995
1119
  */
996
1120
  static VALUE oci8_set_action(VALUE self, VALUE val)
997
1121
  {
1122
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
998
1123
  const char *ptr;
999
1124
  ub4 size;
1000
1125
 
@@ -1008,9 +1133,9 @@ static VALUE oci8_set_action(VALUE self, VALUE val)
1008
1133
  }
1009
1134
  if (oracle_client_version >= ORAVER_10_1) {
1010
1135
  /* Oracle 10g or upper */
1011
- chker2(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, (dvoid*)ptr,
1136
+ chker2(OCIAttrSet(svcctx->usrhp, OCI_HTYPE_SESSION, (dvoid*)ptr,
1012
1137
  size, OCI_ATTR_ACTION, oci8_errhp),
1013
- DATA_PTR(self));
1138
+ &svcctx->base);
1014
1139
  } else {
1015
1140
  /* Oracle 9i or lower */
1016
1141
  oci8_exec_sql_var_t bind_vars[1];
@@ -1022,7 +1147,7 @@ static VALUE oci8_set_action(VALUE self, VALUE val)
1022
1147
  bind_vars[0].indp = NULL;
1023
1148
  bind_vars[0].alenp = NULL;
1024
1149
 
1025
- oci8_exec_sql(oci8_get_svcctx(self),
1150
+ oci8_exec_sql(svcctx,
1026
1151
  "BEGIN\n"
1027
1152
  " DBMS_APPLICATION_INFO.SET_ACTION(:action);\n"
1028
1153
  "END;\n", 0, NULL, 1, bind_vars, 1);
@@ -1031,33 +1156,31 @@ static VALUE oci8_set_action(VALUE self, VALUE val)
1031
1156
  }
1032
1157
 
1033
1158
  /*
1034
- * call-seq:
1035
- * client_info = string or nil
1159
+ * @overload client_info=(client_info)
1036
1160
  *
1037
- * Sets additional information about the client application.
1038
- * This information is stored in the V$SESSION view.
1161
+ * Sets the specified value to {V$SESSION.CLIENT_INFO}[http://docs.oracle.com/database/121/REFRN/refrn30223.htm#r44c1-t21].
1039
1162
  *
1040
- * === Oracle 10g client or upper
1163
+ * === Oracle 10g client or upper
1041
1164
  *
1042
- * This doesn't perform network round trips. The change is reflected
1043
- * to the server by the next round trip such as OCI8#exec, OCI8#ping,
1044
- * etc.
1165
+ * The specified value is sent to the server by piggybacking on the next network
1166
+ * round trip issued by {OCI8#exec}, {OCI8#ping} and so on.
1045
1167
  *
1046
- * === Oracle 9i client or lower
1168
+ * === Oracle 9i client or lower
1047
1169
  *
1048
- * This executes the following PL/SQL block internally.
1049
- * The change is reflected immediately by a network round trip.
1170
+ * This executes the following PL/SQL block internally.
1050
1171
  *
1051
- * BEGIN
1052
- * DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:client_info);
1053
- * END;
1172
+ * BEGIN
1173
+ * DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:client_info);
1174
+ * END;
1054
1175
  *
1055
- * 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]
1176
+ * 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]
1056
1177
  *
1057
- * @since 2.0.3
1178
+ * @param [String] client_info
1179
+ * @since 2.0.3
1058
1180
  */
1059
1181
  static VALUE oci8_set_client_info(VALUE self, VALUE val)
1060
1182
  {
1183
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
1061
1184
  const char *ptr;
1062
1185
  ub4 size;
1063
1186
 
@@ -1071,9 +1194,9 @@ static VALUE oci8_set_client_info(VALUE self, VALUE val)
1071
1194
  }
1072
1195
  if (oracle_client_version >= ORAVER_10_1) {
1073
1196
  /* Oracle 10g or upper */
1074
- chker2(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, (dvoid*)ptr,
1197
+ chker2(OCIAttrSet(svcctx->usrhp, OCI_HTYPE_SESSION, (dvoid*)ptr,
1075
1198
  size, OCI_ATTR_CLIENT_INFO, oci8_errhp),
1076
- DATA_PTR(self));
1199
+ &svcctx->base);
1077
1200
  } else {
1078
1201
  /* Oracle 9i or lower */
1079
1202
  oci8_exec_sql_var_t bind_vars[1];
@@ -1085,7 +1208,7 @@ static VALUE oci8_set_client_info(VALUE self, VALUE val)
1085
1208
  bind_vars[0].indp = NULL;
1086
1209
  bind_vars[0].alenp = NULL;
1087
1210
 
1088
- oci8_exec_sql(oci8_get_svcctx(self),
1211
+ oci8_exec_sql(svcctx,
1089
1212
  "BEGIN\n"
1090
1213
  " DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:client_info);\n"
1091
1214
  "END;\n", 0, NULL, 1, bind_vars, 1);
@@ -1101,11 +1224,11 @@ void Init_oci8(VALUE *out)
1101
1224
  oci8_cOCIHandle = rb_define_class("OCIHandle", rb_cObject);
1102
1225
  cOCI8 = rb_define_class("OCI8", oci8_cOCIHandle);
1103
1226
  #endif
1104
- cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_vtable);
1105
- cSession = oci8_define_class_under(cOCI8, "Session", &oci8_dont_free_handle_vtable);
1106
- cServer = oci8_define_class_under(cOCI8, "Server", &oci8_dont_free_handle_vtable);
1107
- cEnvironment = oci8_define_class_under(cOCI8, "Environment", &oci8_dont_free_handle_vtable);
1108
- cProcess = oci8_define_class_under(cOCI8, "Process", &oci8_dont_free_handle_vtable);
1227
+ cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_data_type, oci8_svcctx_alloc);
1228
+ cSession = oci8_define_class_under(cOCI8, "Session", &oci8_session_data_type, oci8_session_alloc);
1229
+ cServer = oci8_define_class_under(cOCI8, "Server", &oci8_server_data_type, oci8_server_alloc);
1230
+ cEnvironment = oci8_define_class_under(cOCI8, "Environment", &oci8_environment_data_type, oci8_environment_alloc);
1231
+ cProcess = oci8_define_class_under(cOCI8, "Process", &oci8_process_data_type, oci8_process_alloc);
1109
1232
  id_at_session_handle = rb_intern("@session_handle");
1110
1233
  id_at_server_handle = rb_intern("@server_handle");
1111
1234
 
@@ -1130,8 +1253,8 @@ void Init_oci8(VALUE *out)
1130
1253
 
1131
1254
  rb_define_const(cOCI8, "VERSION", rb_obj_freeze(rb_usascii_str_new_cstr(OCI8LIB_VERSION)));
1132
1255
  rb_define_singleton_method_nodoc(cOCI8, "oracle_client_vernum", oci8_s_oracle_client_vernum, 0);
1133
- rb_define_singleton_method(cOCI8, "__get_prop", oci8_s_get_prop, 1);
1134
- rb_define_singleton_method(cOCI8, "__set_prop", oci8_s_set_prop, 2);
1256
+ rb_define_singleton_method_nodoc(cOCI8, "__get_prop", oci8_s_get_prop, 1);
1257
+ rb_define_singleton_method_nodoc(cOCI8, "__set_prop", oci8_s_set_prop, 2);
1135
1258
  rb_define_singleton_method(cOCI8, "error_message", oci8_s_error_message, 1);
1136
1259
  rb_define_private_method(cOCI8, "parse_connect_string", oci8_parse_connect_string, 1);
1137
1260
  rb_define_private_method(cOCI8, "logon2", oci8_logon2, 4);
@@ -1159,7 +1282,7 @@ void Init_oci8(VALUE *out)
1159
1282
 
1160
1283
  oci8_svcctx_t *oci8_get_svcctx(VALUE obj)
1161
1284
  {
1162
- return (oci8_svcctx_t *)oci8_get_handle(obj, cOCI8);
1285
+ return (oci8_svcctx_t *)oci8_check_typeddata(obj, &oci8_svcctx_data_type, 1);
1163
1286
  }
1164
1287
 
1165
1288
  OCISession *oci8_get_oci_session(VALUE obj)