ruby-oci8 2.1.7 → 2.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)