ruby-oci8 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +89 -0
- data/Makefile +16 -14
- data/NEWS +36 -0
- data/VERSION +1 -1
- data/dist-files +3 -0
- data/ext/oci8/apiwrap.yml +107 -95
- data/ext/oci8/attr.c +14 -13
- data/ext/oci8/bind.c +4 -4
- data/ext/oci8/encoding.c +1 -1
- data/ext/oci8/env.c +72 -22
- data/ext/oci8/error.c +1 -1
- data/ext/oci8/extconf.rb +8 -2
- data/ext/oci8/lob.c +24 -5
- data/ext/oci8/metadata.c +3 -3
- data/ext/oci8/object.c +10 -5
- data/ext/oci8/oci8.c +87 -2
- data/ext/oci8/oci8.h +70 -16
- data/ext/oci8/oci8lib.c +37 -3
- data/ext/oci8/ocidatetime.c +1 -1
- data/ext/oci8/ocinumber.c +262 -148
- data/ext/oci8/oraconf.rb +63 -63
- data/ext/oci8/oradate.c +1 -1
- data/lib/dbd/OCI8.rb +17 -2
- data/lib/oci8.rb.in +1 -0
- data/lib/oci8/bindtype.rb +295 -0
- data/lib/oci8/oci8.rb +23 -270
- data/test/test_all.rb +12 -3
- data/test/test_appinfo.rb +29 -0
- data/test/test_dbi.rb +1 -1
- data/test/test_encoding.rb +100 -0
- data/test/test_oci8.rb +37 -0
- data/test/test_oranumber.rb +24 -0
- metadata +6 -3
data/ext/oci8/attr.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
* attr.c
|
4
4
|
*
|
5
5
|
* $Author: kubo $
|
6
|
-
* $Date: 2009-
|
6
|
+
* $Date: 2009-05-17 22:07:16 +0900 (Sun, 17 May 2009) $
|
7
7
|
*
|
8
8
|
* Copyright (C) 2002-2007 KUBO Takehiro <kubo@jiubao.org>
|
9
9
|
*/
|
@@ -106,7 +106,8 @@ static VALUE get_rowid_attr(rowid_arg_t *arg)
|
|
106
106
|
* Oracle Server.
|
107
107
|
*/
|
108
108
|
oci8_base_t *svc;
|
109
|
-
oci8_exec_sql_var_t
|
109
|
+
oci8_exec_sql_var_t define_var;
|
110
|
+
oci8_exec_sql_var_t bind_var;
|
110
111
|
|
111
112
|
/* search a connection from the handle */
|
112
113
|
svc = base;
|
@@ -117,19 +118,19 @@ static VALUE get_rowid_attr(rowid_arg_t *arg)
|
|
117
118
|
}
|
118
119
|
}
|
119
120
|
/* :strval */
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
121
|
+
define_var.valuep = buf;
|
122
|
+
define_var.value_sz = sizeof(buf);
|
123
|
+
define_var.dty = SQLT_CHR;
|
124
|
+
define_var.indp = NULL;
|
125
|
+
define_var.alenp = &buflen;
|
125
126
|
/* :rowid */
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
127
|
+
bind_var.valuep = &arg->ridp;
|
128
|
+
bind_var.value_sz = sizeof(void *);
|
129
|
+
bind_var.dty = SQLT_RDD;
|
130
|
+
bind_var.indp = NULL;
|
131
|
+
bind_var.alenp = NULL;
|
131
132
|
/* convert the rowid descriptor to a string value by querying Oracle server. */
|
132
|
-
oci8_exec_sql((oci8_svcctx_t*)svc, "
|
133
|
+
oci8_exec_sql((oci8_svcctx_t*)svc, "SELECT :rid FROM dual", 1, &define_var, 1, &bind_var, 1);
|
133
134
|
if (buflen == 0) {
|
134
135
|
return Qnil;
|
135
136
|
}
|
data/ext/oci8/bind.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
* bind.c
|
4
4
|
*
|
5
5
|
* $Author: kubo $
|
6
|
-
* $Date: 2009-
|
6
|
+
* $Date: 2009-05-17 22:07:16 +0900 (Sun, 17 May 2009) $
|
7
7
|
*
|
8
8
|
* Copyright (C) 2002-2008 KUBO Takehiro <kubo@jiubao.org>
|
9
9
|
*/
|
@@ -46,7 +46,7 @@ static void bind_string_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE len
|
|
46
46
|
} else {
|
47
47
|
sz = NUM2INT(length);
|
48
48
|
}
|
49
|
-
if (sz
|
49
|
+
if (sz < 0) {
|
50
50
|
rb_raise(rb_eArgError, "invalid bind length %d", sz);
|
51
51
|
}
|
52
52
|
sz += sizeof(sb4);
|
@@ -284,8 +284,8 @@ static VALUE bind_float_get(oci8_bind_t *obind, void *data, void *null_struct)
|
|
284
284
|
|
285
285
|
static void bind_float_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
286
286
|
{
|
287
|
-
|
288
|
-
*(double*)data = RFLOAT_VALUE(val);
|
287
|
+
/* val is converted to Float if it isn't Float. */
|
288
|
+
*(double*)data = RFLOAT_VALUE(rb_Float(val));
|
289
289
|
}
|
290
290
|
|
291
291
|
static void bind_float_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
data/ext/oci8/encoding.c
CHANGED
@@ -45,7 +45,7 @@ VALUE oci8_charset_id2name(VALUE svc, VALUE csid)
|
|
45
45
|
char buf[OCI_NLS_MAXBUFSZ];
|
46
46
|
sword rv;
|
47
47
|
|
48
|
-
rv = OCINlsCharSetIdToName(oci8_envhp, TO_ORATEXT(buf), sizeof(buf), FIX2INT(csid));
|
48
|
+
rv = OCINlsCharSetIdToName(oci8_envhp, TO_ORATEXT(buf), sizeof(buf), (ub2)FIX2INT(csid));
|
49
49
|
if (rv != OCI_SUCCESS) {
|
50
50
|
return Qnil;
|
51
51
|
}
|
data/ext/oci8/env.c
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
*/
|
3
|
+
* env.c - part of ruby-oci8
|
4
|
+
*
|
5
|
+
* Copyright (C) 2002-2009 KUBO Takehiro <kubo@jiubao.org>
|
6
|
+
*/
|
8
7
|
#include "oci8.h"
|
9
8
|
|
10
9
|
#if !defined(RUBY_VM)
|
@@ -12,7 +11,37 @@
|
|
12
11
|
#include <util.h>
|
13
12
|
#endif
|
14
13
|
|
15
|
-
|
14
|
+
#ifdef _WIN32
|
15
|
+
#ifdef HAVE_RUBY_WIN32_H
|
16
|
+
#include <ruby/win32.h> /* for rb_w32_getenv() */
|
17
|
+
#else
|
18
|
+
#include <win32/win32.h> /* for rb_w32_getenv() */
|
19
|
+
#endif
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#ifdef HAVE_RUBY_UTIL_H
|
23
|
+
#include <ruby/util.h>
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#ifdef RUBY_VM
|
27
|
+
ub4 oci8_env_mode = OCI_OBJECT | OCI_THREADED;
|
28
|
+
#else
|
29
|
+
ub4 oci8_env_mode = OCI_OBJECT;
|
30
|
+
#endif
|
31
|
+
|
32
|
+
OCIEnv *oci8_global_envhp;
|
33
|
+
|
34
|
+
OCIEnv *oci8_make_envhp(void)
|
35
|
+
{
|
36
|
+
sword rv;
|
37
|
+
|
38
|
+
rv = OCIEnvCreate(&oci8_global_envhp, oci8_env_mode, NULL, NULL, NULL, NULL, 0, NULL);
|
39
|
+
if (rv != OCI_SUCCESS) {
|
40
|
+
oci8_raise_init_error();
|
41
|
+
}
|
42
|
+
return oci8_global_envhp;
|
43
|
+
}
|
44
|
+
|
16
45
|
#ifdef RUBY_VM
|
17
46
|
/*
|
18
47
|
* oci8_errhp is a thread local object in ruby 1.9.
|
@@ -53,17 +82,23 @@ OCIError *oci8_make_errhp(void)
|
|
53
82
|
/*
|
54
83
|
* oci8_errhp is global in ruby 1.8.
|
55
84
|
*/
|
56
|
-
OCIError *
|
85
|
+
OCIError *oci8_global_errhp;
|
86
|
+
|
87
|
+
OCIError *oci8_make_errhp(void)
|
88
|
+
{
|
89
|
+
sword rv;
|
90
|
+
|
91
|
+
rv = OCIHandleAlloc(oci8_envhp, (dvoid *)&oci8_global_errhp, OCI_HTYPE_ERROR, 0, NULL);
|
92
|
+
if (rv != OCI_SUCCESS)
|
93
|
+
oci8_env_raise(oci8_envhp, rv);
|
94
|
+
return oci8_global_errhp;
|
95
|
+
}
|
57
96
|
#endif
|
58
97
|
|
59
98
|
void Init_oci8_env(void)
|
60
99
|
{
|
61
|
-
sword rv;
|
62
100
|
#ifdef RUBY_VM
|
63
|
-
ub4 mode = OCI_OBJECT | OCI_THREADED;
|
64
101
|
int error;
|
65
|
-
#else
|
66
|
-
ub4 mode = OCI_OBJECT;
|
67
102
|
#endif
|
68
103
|
|
69
104
|
#if !defined(RUBY_VM) && !defined(_WIN32)
|
@@ -85,23 +120,38 @@ void Init_oci8_env(void)
|
|
85
120
|
}
|
86
121
|
}
|
87
122
|
#endif /* WIN32 */
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
123
|
+
|
124
|
+
/* workaround code.
|
125
|
+
*
|
126
|
+
* When ORACLE_HOME ends with '/' and the Oracle client is
|
127
|
+
* an instant client lower than 10.2.0.3, OCIEvnCreate()
|
128
|
+
* doesn't work even though the combination of OCIInitialize()
|
129
|
+
* and OCIEnvInit() works fine. Delete the last slash for
|
130
|
+
* a workaround.
|
131
|
+
*/
|
132
|
+
if (oracle_client_version < ORAVERNUM(10, 2, 0, 3, 0)) {
|
133
|
+
#ifdef _WIN32
|
134
|
+
#define DIR_SEP '\\'
|
135
|
+
#else
|
136
|
+
#define DIR_SEP '/'
|
137
|
+
#endif
|
138
|
+
char *home = getenv("ORACLE_HOME");
|
139
|
+
if (home != NULL) {
|
140
|
+
size_t homelen = strlen(home);
|
141
|
+
if (homelen > 0 && home[homelen - 1] == DIR_SEP) {
|
142
|
+
home = ruby_strdup(home);
|
143
|
+
home[homelen - 1] = '\0';
|
144
|
+
ruby_setenv("ORACLE_HOME", home);
|
145
|
+
xfree(home);
|
146
|
+
}
|
147
|
+
}
|
95
148
|
}
|
149
|
+
|
96
150
|
#ifdef RUBY_VM
|
97
151
|
id_thread_key = rb_intern("__oci8_errhp__");
|
98
152
|
error = oci8_tls_key_init(&oci8_tls_key);
|
99
153
|
if (error != 0) {
|
100
154
|
rb_raise(rb_eRuntimeError, "Cannot create thread local key (errno = %d)", error);
|
101
155
|
}
|
102
|
-
#else /* RUBY_VM */
|
103
|
-
rv = OCIHandleAlloc(oci8_envhp, (dvoid *)&oci8_errhp, OCI_HTYPE_ERROR, 0, NULL);
|
104
|
-
if (rv != OCI_SUCCESS)
|
105
|
-
oci8_env_raise(oci8_envhp, rv);
|
106
156
|
#endif
|
107
157
|
}
|
data/ext/oci8/error.c
CHANGED
@@ -157,7 +157,7 @@ static void set_backtrace_and_raise(VALUE exc, const char *file, int line)
|
|
157
157
|
#endif
|
158
158
|
backtrace = rb_funcall(rb_cObject, oci8_id_caller, 0);
|
159
159
|
if (TYPE(backtrace) == T_ARRAY) {
|
160
|
-
snprintf(errmsg, sizeof(errmsg), "%s:%d:in oci8lib
|
160
|
+
snprintf(errmsg, sizeof(errmsg), "%s:%d:in " STRINGIZE(oci8lib) DLEXT, file, line);
|
161
161
|
errmsg[sizeof(errmsg) - 1] = '\0';
|
162
162
|
rb_ary_unshift(backtrace, rb_usascii_str_new_cstr(errmsg));
|
163
163
|
rb_funcall(exc, oci8_id_set_backtrace, 1, backtrace);
|
data/ext/oci8/extconf.rb
CHANGED
@@ -61,7 +61,13 @@ funcs.keys.sort.each do |version|
|
|
61
61
|
puts "checking for Oracle #{verstr} API - #{result}"
|
62
62
|
break if result == 'fail'
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
|
+
have_type('oratext', 'ociap.h')
|
66
|
+
have_type('OCIDateTime*', 'ociap.h')
|
67
|
+
have_type('OCIInterval*', 'ociap.h')
|
68
|
+
have_type('OCICallbackLobRead2', 'ociap.h')
|
69
|
+
have_type('OCICallbackLobWrite2', 'ociap.h')
|
70
|
+
have_type('OCIAdmin*', 'ociap.h')
|
65
71
|
|
66
72
|
if with_config('oracle-version')
|
67
73
|
oci_client_version = with_config('oracle-version').to_i
|
@@ -97,7 +103,6 @@ have_func("localtime_r")
|
|
97
103
|
have_header("intern.h")
|
98
104
|
have_header("util.h")
|
99
105
|
# ruby 1.9 headers
|
100
|
-
have_header("ruby/util.h")
|
101
106
|
have_type('rb_encoding', ['ruby/ruby.h', 'ruby/encoding.h'])
|
102
107
|
|
103
108
|
# $! in C API
|
@@ -122,6 +127,7 @@ else
|
|
122
127
|
raise 'unsupported ruby version: ' + RUBY_VERSION
|
123
128
|
end
|
124
129
|
$defs << "-DInit_oci8lib=Init_#{so_basename}"
|
130
|
+
$defs << "-Doci8lib=#{so_basename}"
|
125
131
|
|
126
132
|
create_header()
|
127
133
|
|
data/ext/oci8/lob.c
CHANGED
@@ -26,6 +26,7 @@ typedef struct {
|
|
26
26
|
ub4 pos;
|
27
27
|
int char_width;
|
28
28
|
ub1 csfrm;
|
29
|
+
ub1 lobtype;
|
29
30
|
enum state state;
|
30
31
|
} oci8_lob_t;
|
31
32
|
|
@@ -149,6 +150,7 @@ static VALUE oci8_lob_do_initialize(int argc, VALUE *argv, VALUE self, ub1 csfrm
|
|
149
150
|
lob->pos = 0;
|
150
151
|
lob->char_width = 1;
|
151
152
|
lob->csfrm = csfrm;
|
153
|
+
lob->lobtype = lobtype;
|
152
154
|
lob->state = S_NO_OPEN_CLOSE;
|
153
155
|
oci8_link_to_parent((oci8_base_t*)lob, (oci8_base_t*)DATA_PTR(svc));
|
154
156
|
if (!NIL_P(val)) {
|
@@ -360,8 +362,14 @@ static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self)
|
|
360
362
|
}
|
361
363
|
v = rb_ary_join(v, Qnil);
|
362
364
|
OBJ_TAINT(v);
|
363
|
-
|
364
|
-
|
365
|
+
if (lob->lobtype == OCI_TEMP_CLOB) {
|
366
|
+
/* set encoding */
|
367
|
+
rb_enc_associate(v, oci8_encoding);
|
368
|
+
return rb_str_conv_enc(v, oci8_encoding, rb_default_internal_encoding());
|
369
|
+
} else {
|
370
|
+
/* ASCII-8BIT */
|
371
|
+
return v;
|
372
|
+
}
|
365
373
|
}
|
366
374
|
|
367
375
|
static VALUE oci8_lob_write(VALUE self, VALUE data)
|
@@ -371,7 +379,11 @@ static VALUE oci8_lob_write(VALUE self, VALUE data)
|
|
371
379
|
ub4 amt;
|
372
380
|
|
373
381
|
lob_open(lob);
|
374
|
-
|
382
|
+
if (lob->lobtype == OCI_TEMP_CLOB) {
|
383
|
+
OCI8StringValue(data);
|
384
|
+
} else {
|
385
|
+
StringValue(data);
|
386
|
+
}
|
375
387
|
amt = RSTRING_LEN(data);
|
376
388
|
oci_lc(OCILobWrite_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &amt, lob->pos + 1, RSTRING_PTR(data), amt, OCI_ONE_PIECE, NULL, NULL, 0, lob->csfrm));
|
377
389
|
lob->pos += amt;
|
@@ -483,9 +495,15 @@ static void oci8_bfile_set_name(VALUE self, VALUE dir_alias, VALUE filename)
|
|
483
495
|
oci8_lob_t *lob = DATA_PTR(self);
|
484
496
|
|
485
497
|
bfile_close(lob);
|
498
|
+
if (RSTRING_LEN(dir_alias) > UB2MAXVAL) {
|
499
|
+
rb_raise(rb_eRuntimeError, "dir_alias is too long.");
|
500
|
+
}
|
501
|
+
if (RSTRING_LEN(filename) > UB2MAXVAL) {
|
502
|
+
rb_raise(rb_eRuntimeError, "filename is too long.");
|
503
|
+
}
|
486
504
|
oci_lc(OCILobFileSetName(oci8_envhp, oci8_errhp, &lob->base.hp.lob,
|
487
|
-
RSTRING_ORATEXT(dir_alias), RSTRING_LEN(dir_alias),
|
488
|
-
RSTRING_ORATEXT(filename), RSTRING_LEN(filename)));
|
505
|
+
RSTRING_ORATEXT(dir_alias), (ub2)RSTRING_LEN(dir_alias),
|
506
|
+
RSTRING_ORATEXT(filename), (ub2)RSTRING_LEN(filename)));
|
489
507
|
}
|
490
508
|
|
491
509
|
static VALUE oci8_bfile_initialize(int argc, VALUE *argv, VALUE self)
|
@@ -503,6 +521,7 @@ static VALUE oci8_bfile_initialize(int argc, VALUE *argv, VALUE self)
|
|
503
521
|
lob->pos = 0;
|
504
522
|
lob->char_width = 1;
|
505
523
|
lob->csfrm = SQLCS_IMPLICIT;
|
524
|
+
lob->lobtype = OCI_TEMP_BLOB;
|
506
525
|
lob->state = S_BFILE_CLOSE;
|
507
526
|
if (argc != 1) {
|
508
527
|
OCI8SafeStringValue(dir_alias);
|
data/ext/oci8/metadata.c
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
/*
|
3
3
|
* metadata.c
|
4
4
|
*
|
5
|
-
* Copyright (C) 2006-
|
5
|
+
* Copyright (C) 2006-2009 KUBO Takehiro <kubo@jiubao.org>
|
6
6
|
*
|
7
7
|
* implement private methods of classes in OCI8::Metadata module.
|
8
8
|
*
|
@@ -210,7 +210,7 @@ static VALUE metadata_get_oraint(VALUE self, VALUE idx)
|
|
210
210
|
memset(&on, 0, sizeof(on));
|
211
211
|
on.OCINumberPart[0] = size;
|
212
212
|
memcpy(&on.OCINumberPart[1], value, size);
|
213
|
-
return oci8_make_integer(&on);
|
213
|
+
return oci8_make_integer(&on, oci8_errhp);
|
214
214
|
}
|
215
215
|
|
216
216
|
static VALUE metadata_get_param(VALUE self, VALUE idx)
|
@@ -277,7 +277,7 @@ static VALUE oci8_do_describe(VALUE self, void *objptr, ub4 objlen, ub1 objtype,
|
|
277
277
|
oci_lc(OCIAttrSet(desc->hp.dschp, OCI_HTYPE_DESCRIBE, &val, 0, OCI_ATTR_DESC_PUBLIC, oci8_errhp));
|
278
278
|
}
|
279
279
|
oci_lc(OCIDescribeAny_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, objptr, objlen,
|
280
|
-
objtype, OCI_DEFAULT, FIX2INT(type), desc->hp.dschp));
|
280
|
+
objtype, OCI_DEFAULT, (ub1)FIX2INT(type), desc->hp.dschp));
|
281
281
|
oci_lc(OCIAttrGet(desc->hp.dschp, OCI_HTYPE_DESCRIBE, &parmhp, 0, OCI_ATTR_PARAM, oci8_errhp));
|
282
282
|
return oci8_metadata_create(parmhp, self, obj);
|
283
283
|
}
|
data/ext/oci8/object.c
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
+
* Copyright (C) 2002-2009 KUBO Takehiro <kubo@jiubao.org>
|
4
|
+
*/
|
5
|
+
|
6
|
+
/*
|
7
|
+
*
|
3
8
|
* Document-class: OCI8::TDO
|
4
9
|
*
|
5
10
|
* OCI8::TDO is the class for Type Descriptor Object, which describe
|
@@ -157,11 +162,11 @@ static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *dat
|
|
157
162
|
return rb_str_new(TO_CHARPTR(OCIRawPtr(oci8_envhp, *(OCIRaw **)data)),
|
158
163
|
OCIRawSize(oci8_envhp, *(OCIRaw **)data));
|
159
164
|
case ATTR_OCINUMBER:
|
160
|
-
return oci8_make_ocinumber((OCINumber *)data);
|
165
|
+
return oci8_make_ocinumber((OCINumber *)data, oci8_errhp);
|
161
166
|
case ATTR_FLOAT:
|
162
|
-
return oci8_make_float((OCINumber *)data);
|
167
|
+
return oci8_make_float((OCINumber *)data, oci8_errhp);
|
163
168
|
case ATTR_INTEGER:
|
164
|
-
return oci8_make_integer((OCINumber *)data);
|
169
|
+
return oci8_make_integer((OCINumber *)data, oci8_errhp);
|
165
170
|
case ATTR_BINARY_DOUBLE:
|
166
171
|
return rb_float_new(*(double*)data);
|
167
172
|
case ATTR_BINARY_FLOAT:
|
@@ -431,10 +436,10 @@ static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data
|
|
431
436
|
break;
|
432
437
|
case ATTR_OCINUMBER:
|
433
438
|
case ATTR_FLOAT:
|
434
|
-
oci8_set_ocinumber((OCINumber*)data, val);
|
439
|
+
oci8_set_ocinumber((OCINumber*)data, val, oci8_errhp);
|
435
440
|
break;
|
436
441
|
case ATTR_INTEGER:
|
437
|
-
oci8_set_integer((OCINumber*)data, val);
|
442
|
+
oci8_set_integer((OCINumber*)data, val, oci8_errhp);
|
438
443
|
break;
|
439
444
|
case ATTR_BINARY_DOUBLE:
|
440
445
|
*(double*)data = NUM2DBL(val);
|
data/ext/oci8/oci8.c
CHANGED
@@ -17,6 +17,10 @@ extern rb_pid_t rb_w32_getpid(void);
|
|
17
17
|
#endif
|
18
18
|
#endif
|
19
19
|
|
20
|
+
#ifndef OCI_ATTR_CLIENT_IDENTIFIER
|
21
|
+
#define OCI_ATTR_CLIENT_IDENTIFIER 278
|
22
|
+
#endif
|
23
|
+
|
20
24
|
/*
|
21
25
|
* Document-class: OCI8
|
22
26
|
*
|
@@ -538,11 +542,11 @@ static VALUE oci8_oracle_server_vernum(VALUE self)
|
|
538
542
|
|
539
543
|
if (have_OCIServerRelease) {
|
540
544
|
/* Oracle 9i or later */
|
541
|
-
oci_lc(OCIServerRelease(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), svcctx->base.type, &version));
|
545
|
+
oci_lc(OCIServerRelease(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), (ub1)svcctx->base.type, &version));
|
542
546
|
return UINT2NUM(version);
|
543
547
|
} else {
|
544
548
|
/* Oracle 8.x */
|
545
|
-
oci_lc(OCIServerVersion(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), svcctx->base.type));
|
549
|
+
oci_lc(OCIServerVersion(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), (ub1)svcctx->base.type));
|
546
550
|
if ((p = strchr(buf, '.')) != NULL) {
|
547
551
|
unsigned int major, minor, update, patch, port_update;
|
548
552
|
while (p >= buf && *p != ' ') {
|
@@ -556,6 +560,85 @@ static VALUE oci8_oracle_server_vernum(VALUE self)
|
|
556
560
|
}
|
557
561
|
}
|
558
562
|
|
563
|
+
/*
|
564
|
+
* call-seq:
|
565
|
+
* ping -> true or false
|
566
|
+
*
|
567
|
+
* Verifies that the Oracle connection is alive.
|
568
|
+
*
|
569
|
+
* OCI8#ping also can be used to flush all the pending OCI client-side calls
|
570
|
+
* to the server if any exist. See: OCI8#client_identifier=.
|
571
|
+
*
|
572
|
+
* For Oracle 10.2 client or upper, a dummy round trip call is made by a newly
|
573
|
+
* added OCI function in Oracle 10.2.
|
574
|
+
*
|
575
|
+
* For Oracle 10.1 client or lower, a simple PL/SQL block "BEGIN NULL; END;"
|
576
|
+
* is executed to make a round trip call.
|
577
|
+
*/
|
578
|
+
static VALUE oci8_ping(VALUE self)
|
579
|
+
{
|
580
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
|
581
|
+
sword rv;
|
582
|
+
|
583
|
+
if (have_OCIPing_nb) {
|
584
|
+
/* Oracle 10.2 or upper */
|
585
|
+
rv = OCIPing_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT);
|
586
|
+
} else {
|
587
|
+
/* Oracle 10.1 or lower */
|
588
|
+
rv = oci8_exec_sql(svcctx, "BEGIN NULL; END;", 0U, NULL, 0U, NULL, 0);
|
589
|
+
}
|
590
|
+
return rv == OCI_SUCCESS ? Qtrue : FALSE;
|
591
|
+
}
|
592
|
+
|
593
|
+
/*
|
594
|
+
* call-seq:
|
595
|
+
* client_identifier = string
|
596
|
+
*
|
597
|
+
* Sets the CLIENT_IDENTIFIER column in the V$SESSION dictionary view.
|
598
|
+
* This can be up to 64 bytes long. The first character should not be ':'.
|
599
|
+
*
|
600
|
+
* If the Oracle client is 9i or upper, the change is not reflected to the
|
601
|
+
* server immediately. It is postponed until the next round trip call for
|
602
|
+
* example OCI8#exec, OCI8#ping, etc.
|
603
|
+
*
|
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
|
+
*/
|
607
|
+
static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
|
608
|
+
{
|
609
|
+
OCISession *sess = oci8_get_oci_session(self);
|
610
|
+
char *ptr;
|
611
|
+
ub4 size;
|
612
|
+
|
613
|
+
if (!NIL_P(val)) {
|
614
|
+
OCI8SafeStringValue(val);
|
615
|
+
ptr = RSTRING_PTR(val);
|
616
|
+
size = RSTRING_LEN(val);
|
617
|
+
} else {
|
618
|
+
ptr = "";
|
619
|
+
size = 0;
|
620
|
+
}
|
621
|
+
if (oracle_client_version >= 900) {
|
622
|
+
if (size > 0 && ptr[0] == ':') {
|
623
|
+
rb_raise(rb_eArgError, "client identifier should not start with ':'.");
|
624
|
+
}
|
625
|
+
oci_lc(OCIAttrSet(sess, OCI_HTYPE_SESSION, ptr,
|
626
|
+
size, OCI_ATTR_CLIENT_IDENTIFIER, oci8_errhp));
|
627
|
+
} else {
|
628
|
+
oci8_exec_sql_var_t bind_vars[1];
|
629
|
+
|
630
|
+
/* :client_id */
|
631
|
+
bind_vars[0].valuep = ptr;
|
632
|
+
bind_vars[0].value_sz = size;
|
633
|
+
bind_vars[0].dty = SQLT_CHR;
|
634
|
+
bind_vars[0].indp = NULL;
|
635
|
+
bind_vars[0].alenp = NULL;
|
636
|
+
|
637
|
+
oci8_exec_sql(oci8_get_svcctx(self), "BEGIN DBMS_SESSION.SET_IDENTIFIER(:client_id); END;", 0, NULL, 1, bind_vars, 1);
|
638
|
+
}
|
639
|
+
return val;
|
640
|
+
}
|
641
|
+
|
559
642
|
VALUE Init_oci8(void)
|
560
643
|
{
|
561
644
|
cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_class);
|
@@ -589,6 +672,8 @@ VALUE Init_oci8(void)
|
|
589
672
|
rb_define_method(cOCI8, "break", oci8_break, 0);
|
590
673
|
rb_define_method(cOCI8, "prefetch_rows=", oci8_set_prefetch_rows, 1);
|
591
674
|
rb_define_private_method(cOCI8, "oracle_server_vernum", oci8_oracle_server_vernum, 0);
|
675
|
+
rb_define_method(cOCI8, "ping", oci8_ping, 0);
|
676
|
+
rb_define_method(cOCI8, "client_identifier=", oci8_set_client_identifier, 1);
|
592
677
|
return cOCI8;
|
593
678
|
}
|
594
679
|
|