Class: OCI8

Inherits:
OCIHandle show all
Defined in:
lib/oci8/oci8.rb,
lib/oci8/compat.rb,
lib/oci8/object.rb,
lib/oci8/object.rb,
lib/oci8/bindtype.rb,
lib/oci8/datetime.rb,
lib/oci8/metadata.rb,
lib/oci8/properties.rb,
lib/oci8/oracle_version.rb,
lib/oci8/connection_pool.rb,
ext/oci8/stmt.c,
ext/oci8/encoding.c,
ext/oci8/connection_pool.c

Overview

– connection_pool.rb – OCI8::ConnectionPool

Copyright © 2010 KUBO Takehiro <[email protected]> ++

Defined Under Namespace

Modules: BindType, Math, Metadata, Object, Win32Util Classes: BFILE, BLOB, BindArgumentHelper, CLOB, ConnectionPool, Cursor, NCLOB, NamedCollection, NamedType, OracleVersion, TDO

Constant Summary collapse

STMT_SELECT =
:select_stmt
STMT_UPDATE =
:update_stmt
STMT_DELETE =
:delete_stmt
STMT_INSERT =
:insert_stmt
STMT_CREATE =
:create_stmt
STMT_DROP =
:drop_stmt
STMT_ALTER =
:alter_stmt
STMT_BEGIN =
:begin_stmt
STMT_DECLARE =
:declare_stmt
RAW =
:raw
SQLT_CHR =

varchar, varchar2

:varchar2
SQLT_NUM =

number, double precision, float, real, numeric, int, integer, smallint

:number
SQLT_LNG =

long

:long
SQLT_DAT =

date

:date
SQLT_BIN =

raw

:raw
SQLT_LBI =

long raw

:long_raw
SQLT_AFC =

char

:char
SQLT_IBFLOAT =

binary_float

:binary_float
SQLT_IBDOUBLE =

binary_double

:binary_double
SQLT_RDD =

rowid

:rowid
SQLT_CLOB =

clob

:clob
SQLT_BLOB =

blob

:blob
SQLT_BFILE =

bfile

:bfile
SQLT_RSET =

ref cursor

116
SQLT_TIMESTAMP =

timestamp

:timestamp
SQLT_TIMESTAMP_TZ =

timestamp with time zone

:timestamp_tz
SQLT_INTERVAL_YM =

interval year to month

:interval_ym
SQLT_INTERVAL_DS =

interval day to second

:interval_ds
SQLT_TIMESTAMP_LTZ =

timestamp with local time zone

:timestamp_ltz
SQLT_NAMES =

mapping of sql type number to sql type name.

{}
@@properties =
{
  :length_semantics => :byte,
  :bind_string_as_nchar => false,
  :float_conversion_type => :ruby,
}

Constants inherited from OCIHandle

OCIHandle::OCI_ATTR_ACTION_CONTEXT, OCIHandle::OCI_ATTR_AUTOCOMMIT_DDL, OCIHandle::OCI_ATTR_CACHE, OCIHandle::OCI_ATTR_CATALOG_LOCATION, OCIHandle::OCI_ATTR_CHARSET_FORM, OCIHandle::OCI_ATTR_CHARSET_ID, OCIHandle::OCI_ATTR_CHAR_SIZE, OCIHandle::OCI_ATTR_CHAR_USED, OCIHandle::OCI_ATTR_CLIENT_IDENTIFIER, OCIHandle::OCI_ATTR_CLUSTERED, OCIHandle::OCI_ATTR_COLLECTION_ELEMENT, OCIHandle::OCI_ATTR_COLLECTION_TYPECODE, OCIHandle::OCI_ATTR_COMMENT, OCIHandle::OCI_ATTR_CONDITION, OCIHandle::OCI_ATTR_CONN_BUSY_COUNT, OCIHandle::OCI_ATTR_CONN_INCR, OCIHandle::OCI_ATTR_CONN_MAX, OCIHandle::OCI_ATTR_CONN_MIN, OCIHandle::OCI_ATTR_CONN_NOWAIT, OCIHandle::OCI_ATTR_CONN_OPEN_COUNT, OCIHandle::OCI_ATTR_CONN_TIMEOUT, OCIHandle::OCI_ATTR_CURSOR_COMMIT_BEHAVIOR, OCIHandle::OCI_ATTR_DATA_SIZE, OCIHandle::OCI_ATTR_DATA_TYPE, OCIHandle::OCI_ATTR_DESC_SYNBASE, OCIHandle::OCI_ATTR_DURATION, OCIHandle::OCI_ATTR_ENCAPSULATION, OCIHandle::OCI_ATTR_EVALUATION_FUNCTION, OCIHandle::OCI_ATTR_EVAL_CONTEXT_NAME, OCIHandle::OCI_ATTR_EVAL_CONTEXT_OWNER, OCIHandle::OCI_ATTR_FSPRECISION, OCIHandle::OCI_ATTR_HAS_DEFAULT, OCIHandle::OCI_ATTR_HAS_FILE, OCIHandle::OCI_ATTR_HAS_LOB, OCIHandle::OCI_ATTR_HAS_NESTED_TABLE, OCIHandle::OCI_ATTR_HAS_RESULT, OCIHandle::OCI_ATTR_HW_MARK, OCIHandle::OCI_ATTR_INCR, OCIHandle::OCI_ATTR_INDEX_ONLY, OCIHandle::OCI_ATTR_IOMODE, OCIHandle::OCI_ATTR_IS_CONSTANT, OCIHandle::OCI_ATTR_IS_CONSTRUCTOR, OCIHandle::OCI_ATTR_IS_DESTRUCTOR, OCIHandle::OCI_ATTR_IS_FINAL_METHOD, OCIHandle::OCI_ATTR_IS_FINAL_TYPE, OCIHandle::OCI_ATTR_IS_INCOMPLETE_TYPE, OCIHandle::OCI_ATTR_IS_INLINE, OCIHandle::OCI_ATTR_IS_INSTANTIABLE_METHOD, OCIHandle::OCI_ATTR_IS_INSTANTIABLE_TYPE, OCIHandle::OCI_ATTR_IS_INVOKER_RIGHTS, OCIHandle::OCI_ATTR_IS_MAP, OCIHandle::OCI_ATTR_IS_NULL, OCIHandle::OCI_ATTR_IS_OPERATOR, OCIHandle::OCI_ATTR_IS_ORDER, OCIHandle::OCI_ATTR_IS_OVERRIDING_METHOD, OCIHandle::OCI_ATTR_IS_PREDEFINED_TYPE, OCIHandle::OCI_ATTR_IS_RNDS, OCIHandle::OCI_ATTR_IS_RNPS, OCIHandle::OCI_ATTR_IS_SELFISH, OCIHandle::OCI_ATTR_IS_SUBTYPE, OCIHandle::OCI_ATTR_IS_SYSTEM_GENERATED_TYPE, OCIHandle::OCI_ATTR_IS_SYSTEM_TYPE, OCIHandle::OCI_ATTR_IS_TEMPORARY, OCIHandle::OCI_ATTR_IS_TRANSIENT_TYPE, OCIHandle::OCI_ATTR_IS_TYPED, OCIHandle::OCI_ATTR_IS_VIRTUAL, OCIHandle::OCI_ATTR_IS_WNDS, OCIHandle::OCI_ATTR_IS_WNPS, OCIHandle::OCI_ATTR_LEVEL, OCIHandle::OCI_ATTR_LFPRECISION, OCIHandle::OCI_ATTR_LINK, OCIHandle::OCI_ATTR_LIST_ARGUMENTS, OCIHandle::OCI_ATTR_LIST_COLUMNS, OCIHandle::OCI_ATTR_LIST_OBJECTS, OCIHandle::OCI_ATTR_LIST_SCHEMAS, OCIHandle::OCI_ATTR_LIST_SUBPROGRAMS, OCIHandle::OCI_ATTR_LIST_TABLE_ALIASES, OCIHandle::OCI_ATTR_LIST_TYPE_ATTRS, OCIHandle::OCI_ATTR_LIST_TYPE_METHODS, OCIHandle::OCI_ATTR_LIST_VARIABLE_TYPES, OCIHandle::OCI_ATTR_LOCKING_MODE, OCIHandle::OCI_ATTR_LTYPE, OCIHandle::OCI_ATTR_MAP_METHOD, OCIHandle::OCI_ATTR_MAX, OCIHandle::OCI_ATTR_MAX_CATALOG_NAMELEN, OCIHandle::OCI_ATTR_MAX_COLUMN_LEN, OCIHandle::OCI_ATTR_MAX_PROC_LEN, OCIHandle::OCI_ATTR_MIN, OCIHandle::OCI_ATTR_NAME, OCIHandle::OCI_ATTR_NCHARSET_ID, OCIHandle::OCI_ATTR_NOWAIT_SUPPORT, OCIHandle::OCI_ATTR_NUM_ARGS, OCIHandle::OCI_ATTR_NUM_COLS, OCIHandle::OCI_ATTR_NUM_ELEMS, OCIHandle::OCI_ATTR_NUM_PARAMS, OCIHandle::OCI_ATTR_NUM_TYPE_ATTRS, OCIHandle::OCI_ATTR_NUM_TYPE_METHODS, OCIHandle::OCI_ATTR_OBJID, OCIHandle::OCI_ATTR_OBJ_ID, OCIHandle::OCI_ATTR_OBJ_NAME, OCIHandle::OCI_ATTR_OBJ_SCHEMA, OCIHandle::OCI_ATTR_ORDER, OCIHandle::OCI_ATTR_ORDER_METHOD, OCIHandle::OCI_ATTR_OVERLOAD, OCIHandle::OCI_ATTR_OVERLOAD_ID, OCIHandle::OCI_ATTR_PARTITIONED, OCIHandle::OCI_ATTR_PASSWORD, OCIHandle::OCI_ATTR_PDPRC, OCIHandle::OCI_ATTR_PDSCL, OCIHandle::OCI_ATTR_POSITION, OCIHandle::OCI_ATTR_PRECISION, OCIHandle::OCI_ATTR_RADIX, OCIHandle::OCI_ATTR_RDBA, OCIHandle::OCI_ATTR_REF_TDO, OCIHandle::OCI_ATTR_SAVEPOINT_SUPPORT, OCIHandle::OCI_ATTR_SCALE, OCIHandle::OCI_ATTR_SCHEMA_NAME, OCIHandle::OCI_ATTR_SUB_NAME, OCIHandle::OCI_ATTR_SUPERTYPE_NAME, OCIHandle::OCI_ATTR_SUPERTYPE_SCHEMA_NAME, OCIHandle::OCI_ATTR_TABLESPACE, OCIHandle::OCI_ATTR_TABLE_NAME, OCIHandle::OCI_ATTR_TIMESTAMP, OCIHandle::OCI_ATTR_TYPECODE, OCIHandle::OCI_ATTR_TYPE_NAME, OCIHandle::OCI_ATTR_TYPE_SCHEMA, OCIHandle::OCI_ATTR_USERNAME, OCIHandle::OCI_ATTR_VALUE, OCIHandle::OCI_ATTR_VAR_METHOD_FUNCTION, OCIHandle::OCI_ATTR_VAR_TYPE, OCIHandle::OCI_ATTR_VAR_VALUE_FUNCTION, OCIHandle::OCI_ATTR_VERSION, OCIHandle::OCI_CPOOL, OCIHandle::OCI_CRED_EXT, OCIHandle::OCI_CRED_RDBMS, OCIHandle::OCI_DEFAULT, OCIHandle::OCI_DURATION_BEGIN, OCIHandle::OCI_DURATION_CALL, OCIHandle::OCI_DURATION_CALLOUT, OCIHandle::OCI_DURATION_DEFAULT, OCIHandle::OCI_DURATION_INVALID, OCIHandle::OCI_DURATION_NEXT, OCIHandle::OCI_DURATION_NULL, OCIHandle::OCI_DURATION_SESSION, OCIHandle::OCI_DURATION_STATEMENT, OCIHandle::OCI_DURATION_TRANS, OCIHandle::OCI_DURATION_USER_CALLBACK, OCIHandle::OCI_LTYPE_ARG_FUNC, OCIHandle::OCI_LTYPE_ARG_PROC, OCIHandle::OCI_LTYPE_COLUMN, OCIHandle::OCI_LTYPE_DB_SCH, OCIHandle::OCI_LTYPE_NAME_VALUE, OCIHandle::OCI_LTYPE_SCH_OBJ, OCIHandle::OCI_LTYPE_SUBPRG, OCIHandle::OCI_LTYPE_TABLE_ALIAS, OCIHandle::OCI_LTYPE_TYPE_ARG_FUNC, OCIHandle::OCI_LTYPE_TYPE_ARG_PROC, OCIHandle::OCI_LTYPE_TYPE_ATTR, OCIHandle::OCI_LTYPE_TYPE_METHOD, OCIHandle::OCI_LTYPE_TYPE_SUBTYPE, OCIHandle::OCI_LTYPE_UNK, OCIHandle::OCI_LTYPE_VARIABLE_TYPE, OCIHandle::OCI_PTYPE_ARG, OCIHandle::OCI_PTYPE_COL, OCIHandle::OCI_PTYPE_DATABASE, OCIHandle::OCI_PTYPE_EVALUATION_CONTEXT, OCIHandle::OCI_PTYPE_FUNC, OCIHandle::OCI_PTYPE_LIST, OCIHandle::OCI_PTYPE_NAME_VALUE, OCIHandle::OCI_PTYPE_PKG, OCIHandle::OCI_PTYPE_PROC, OCIHandle::OCI_PTYPE_RULE, OCIHandle::OCI_PTYPE_RULE_SET, OCIHandle::OCI_PTYPE_SCHEMA, OCIHandle::OCI_PTYPE_SEQ, OCIHandle::OCI_PTYPE_SYN, OCIHandle::OCI_PTYPE_TABLE, OCIHandle::OCI_PTYPE_TABLE_ALIAS, OCIHandle::OCI_PTYPE_TYPE, OCIHandle::OCI_PTYPE_TYPE_ARG, OCIHandle::OCI_PTYPE_TYPE_ATTR, OCIHandle::OCI_PTYPE_TYPE_COLL, OCIHandle::OCI_PTYPE_TYPE_METHOD, OCIHandle::OCI_PTYPE_TYPE_RESULT, OCIHandle::OCI_PTYPE_UNK, OCIHandle::OCI_PTYPE_VARIABLE_TYPE, OCIHandle::OCI_PTYPE_VIEW, OCIHandle::OCI_SYSDBA, OCIHandle::OCI_SYSOPER

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ OCI8

call-seq:

new(username, password, dbname = nil, privilege = nil)

Connects to an Oracle database server by username and password at dbname as privilege.

connecting to the local server

Set username and password or pass “username/password” as a single argument.

OCI8.new('scott', 'tiger')

or

OCI8.new('scott/tiger')

connecting to a remote server

Set username, password and dbname or pass “username/password@dbname” as a single argument.

OCI8.new('scott', 'tiger', 'orcl.world')

or

OCI8.new('scott/[email protected]')

The dbname is a net service name or an easy connectection identifier. The former is a name listed in the file tnsnames.ora. Ask to your DBA if you don’t know what it is. The latter has the syntax as “//host:port/service_name”.

OCI8.new('scott', 'tiger', '//remote-host:1521/XE')

or

OCI8.new('scott/tiger@//remote-host:1521/XE')

connecting as a privileged user

Set :SYSDBA or :SYSOPER to privilege, otherwise “username/password as sysdba” or “username/password as sysoper” as a single argument.

OCI8.new('sys', 'change_on_install', nil, :SYSDBA)

or

OCI8.new('sys/change_on_install as sysdba')

external OS authentication

Set nil to username and password, or “/” as a single argument.

OCI8.new(nil, nil)

or

OCI8.new('/')

To connect to a remote host:

OCI8.new(nil, nil, 'dbname')

or

OCI8.new('/@dbname')

proxy authentication

Enclose end user’s username with square brackets and add it at the end of proxy user’s username.

OCI8.new('proxy_user_name[end_user_name]', 'proxy_password')

or

OCI8.new('proxy_user_name[end_user_name]/proxy_password')


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/oci8/oci8.rb', line 95

def initialize(*args)
  if args.length == 1
    username, password, dbname, mode = parse_connect_string(args[0])
  else
    username, password, dbname, mode = args
  end

  if username.nil? and password.nil?
    cred = OCI_CRED_EXT
  end
  case mode
  when :SYSDBA
    mode = OCI_SYSDBA
  when :SYSOPER
    mode = OCI_SYSOPER
  when nil
    # do nothing
  else
    raise "unknown privilege type #{mode}"
  end

  if mode.nil? and cred.nil? and (not dbname.is_a? OCI8::ConnectionPool)
    # logon by the OCI function OCILogon().
    logon(username, password, dbname)
  else
    # logon by the OCI function OCISessionBegin().
    if dbname.is_a? OCI8::ConnectionPool
      @pool = dbname # to prevent GC from freeing the connection pool.
      attach_mode = OCI_CPOOL
      dbname = dbname.send(:pool_name)
    else
      attach_mode = OCI_DEFAULT
    end

    allocate_handles()
    session_handle.send(:attr_set_string, OCI_ATTR_USERNAME, username) if username
    session_handle.send(:attr_set_string, OCI_ATTR_PASSWORD, password) if password
    server_attach(dbname, attach_mode)
    session_begin(cred ? cred : OCI_CRED_RDBMS, mode ? mode : OCI_DEFAULT)
  end

  @prefetch_rows = nil
  @username = nil
end

Class Method Details

.[](name) ⇒ Object

Raises:



13
14
15
16
# File 'lib/oci8/properties.rb', line 13

def @@properties.[](name)
  raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
  super(name)
end

.[]=(name, val) ⇒ Object

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/oci8/properties.rb', line 18

def @@properties.[]=(name, val)
  raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
  case name
  when :length_semantic
    if val != :byte and val != char
      raise ArgumentError, "Invalid property value #{val} for :length_semantics."
    end
  when :bind_string_as_nchar
    val = val ? true : false
  when :float_conversion_type
    # handled by native code in oci8lib_xx.so.
    OCI8.__set_property(name, val)
  end
  super(name, val)
end

.encodingObject

(new in 2.0.0 and ruby 1.9)

Returns the Oracle client encoding.

When string data, such as SQL statements and bind variables, are passed to Oracle, they are converted to OCI8.encoding in advance.

# When OCI8.encoding is ISO-8859-1,
conn.exec('insert into country_code values(:1, :2, :3)',
          'AT', 'Austria', "\u00d6sterreichs")
# "\u00d6sterreichs" is 'Österreichs' encoded by UTF-8.
# It is converted to ISO-8859-1 before it is passed to
# the Oracle C API.

When string data, such as fetched values and bind variable for output, are retrieved from Oracle, they are encoded by OCI8.encoding if Encoding.default_internal is nil. If it isn’t nil, they are converted from OCI8.encoding to Encoding.default_internal.

If OCI8.encoding is ASCII-8BIT, no encoding conversions are done.



242
243
244
245
# File 'ext/oci8/encoding.c', line 242

static VALUE oci8_get_encoding(VALUE klass)
{
    return rb_enc_from_encoding(oci8_encoding);
}

.encoding=(enc) ⇒ Object

(new in 2.0.0 and ruby 1.9)

Sets Oracle client encoding. You must not use this method. You should set the environment variable NLS_LANG properly to change OCI8.encoding.



257
258
259
260
261
262
263
264
265
# File 'ext/oci8/encoding.c', line 257

static VALUE oci8_set_encoding(VALUE klass, VALUE encoding)
{
    if (NIL_P(encoding)) {
        oci8_encoding = NULL;
    } else {
        oci8_encoding = rb_to_encoding(encoding);
    }
    return encoding;
}

.nls_ratioInteger

(new in 2.1.0)

Gets NLS ratio, maximum number of bytes per one character of the current NLS chracter set. It is a factor to calculate the internal buffer size of a string bind variable whose nls length semantics is char.

Returns:



186
187
188
189
# File 'ext/oci8/encoding.c', line 186

static VALUE oci8_get_nls_ratio(VALUE klass)
{
    return INT2NUM(oci8_nls_ratio);
}

.nls_ratio=(integer) ⇒ Object

(new in 2.1.0)

Sets NLS ratio, maximum number of bytes per one character of the current NLS chracter set. It is initialized in ‘oci8/encoding-init.rb’ when oci8 is required. You have no need to set it explicitly.



201
202
203
204
205
206
207
208
209
# File 'ext/oci8/encoding.c', line 201

static VALUE oci8_set_nls_ratio(VALUE klass, VALUE val)
{
    int v = NUM2INT(val);
    if (v <= 0) {
        rb_raise(rb_eRangeError, "expected a positive integer but %d", v);
    }
    oci8_nls_ratio = v;
    return val;
}

.propertiesObject

call-seq:

OCI8.properties -> a customized Hash

(new in 2.0.5)

Returns a Hash which ruby-oci8 global settings. The hash’s setter and getter methods are customized to check property names and values.

# get properties
OCI8.properties[:bind_string_as_nchar]  # => false
OCI8.properties[:invalid_property_name] # raises an IndexError

# set properties
OCI8.properties[:bind_string_as_nchar] = true
OCI8.properties[:invalid_property_name] = true # raises an IndexError

Supported properties are listed below:

:length_semantics

:char when Oracle character length is counted by the number of characters. :byte when it is counted by the number of bytes. The default setting is :byte because :char causes unexpected behaviour on Oracle 9i.

:bind_string_as_nchar

true when string bind variables are bound as NCHAR, otherwise false. The default value is false.

:float_conversion_type

(new in 2.1.0) Specifies who converts decimal to float and vice versa. It should be either :ruby or :oracle. The default value is :ruby. See: rubyforge.org/forum/forum.php?thread_id=50030&forum_id=1078



70
71
72
# File 'lib/oci8/properties.rb', line 70

def self.properties
  @@properties
end

Instance Method Details

#charset_id2name(charset_id) ⇒ Object

(new in 2.0.0)

Returns the Oracle character set name from the specified character set ID if it is valid. Otherwise, nil is returned.

Oracle 9iR2 client or upper

It is done by using the mapping table stored in the client side.

Oracle 9iR1 client or lower

It executes the following PL/SQL block internally to use the mapping table stored in the server side.

BEGIN
  :name := nls_charset_name(:csid);
END;


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'ext/oci8/encoding.c', line 52

VALUE oci8_charset_id2name(VALUE svc, VALUE csid)
{
    VALUE name = rb_hash_aref(csid2name, csid);

    if (!NIL_P(name)) {
        return name;
    }
    Check_Type(csid, T_FIXNUM);
    if (have_OCINlsCharSetIdToName) {
        /* Oracle 9iR2 or upper */
        char buf[OCI_NLS_MAXBUFSZ];
        sword rv;

        rv = OCINlsCharSetIdToName(oci8_envhp, TO_ORATEXT(buf), sizeof(buf), (ub2)FIX2INT(csid));
        if (rv != OCI_SUCCESS) {
            return Qnil;
        }
        name = rb_usascii_str_new_cstr(buf);
    } else {
        /* Oracle 9iR1 or lower */
        oci8_exec_sql_var_t bind_vars[2];
        char buf[OCI_NLS_MAXBUFSZ];
        ub2 buflen = 0;
        int ival = FIX2INT(csid);

        /* :name */
        bind_vars[0].valuep = buf;
        bind_vars[0].value_sz = OCI_NLS_MAXBUFSZ;
        bind_vars[0].dty = SQLT_CHR;
        bind_vars[0].indp = NULL;
        bind_vars[0].alenp = &buflen;
        /* :csid */
        bind_vars[1].valuep = &ival;
        bind_vars[1].value_sz = sizeof(int);
        bind_vars[1].dty = SQLT_INT;
        bind_vars[1].indp = NULL;
        bind_vars[1].alenp = NULL;

        /* convert chaset id to charset name by querying Oracle server. */
        oci8_exec_sql(oci8_get_svcctx(svc), "BEGIN :name := nls_charset_name(:csid); END;", 0, NULL, 2, bind_vars, 1);
        if (buflen == 0) {
            return Qnil;
        }
        name = rb_usascii_str_new(buf, buflen);
    }
    OBJ_FREEZE(name);
    rb_hash_aset(csid2name, csid, name);
    rb_hash_aset(csname2id, name, csid);
    return name;
}

#charset_name2id(charset_name) ⇒ Object

(new in 2.0.0)

Returns the Oracle character set ID for the specified Oracle character set name if it is valid. Othewise, nil is returned.

Oracle 9iR2 client or upper

It is done by using the mapping table stored in the client side.

Oracle 9iR1 client or lower

It executes the following PL/SQL block internally to use the mapping table stored in the server side.

BEGIN
  :csid := nls_charset_id(:name);
END;


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'ext/oci8/encoding.c', line 126

static VALUE oci8_charset_name2id(VALUE svc, VALUE name)
{
    VALUE csid;

    name = rb_funcall(name, id_upcase, 0);
    csid = rb_hash_aref(csname2id, StringValue(name));
    if (!NIL_P(csid)) {
        return csid;
    }
    if (have_OCINlsCharSetNameToId) {
        /* Oracle 9iR2 or upper */
        ub2 rv;

        rv = OCINlsCharSetNameToId(oci8_envhp, RSTRING_ORATEXT(name));
        if (rv == 0) {
            return Qnil;
        }
        csid = INT2FIX(rv);
    } else {
        /* Oracle 9iR1 or lower */
        oci8_exec_sql_var_t bind_vars[2];
        int ival;
        sb2 ind = 0; /* null indicator */

        /* :csid */
        bind_vars[0].valuep = &ival;
        bind_vars[0].value_sz = sizeof(int);
        bind_vars[0].dty = SQLT_INT;
        bind_vars[0].indp = &ind;
        bind_vars[0].alenp = NULL;
        /* :name */
        bind_vars[1].valuep = RSTRING_PTR(name);
        bind_vars[1].value_sz = RSTRING_LEN(name);
        bind_vars[1].dty = SQLT_CHR;
        bind_vars[1].indp = NULL;
        bind_vars[1].alenp = NULL;

        /* convert chaset name to charset id by querying Oracle server. */
        oci8_exec_sql(oci8_get_svcctx(svc), "BEGIN :csid := nls_charset_id(:name); END;", 0, NULL, 2, bind_vars, 1);
        if (ind) {
            return Qnil;
        }
        csid = INT2FIX(ival);
    }
    rb_hash_aset(csid2name, csid, name);
    rb_hash_aset(csname2id, name, csid);
    return csid;
}

#describe_any(object_name) ⇒ Object

return a subclass of OCI8::Metadata::Base which has information about object_name. OCI8::Metadata::Table, OCI8::Metadata::View, OCI8::Metadata::Procedure, OCI8::Metadata::Function, OCI8::Metadata::Package, OCI8::Metadata::Type, OCI8::Metadata::Synonym or OCI8::Metadata::Sequence



2069
2070
2071
# File 'lib/oci8/metadata.rb', line 2069

def describe_any(object_name)
  __describe(object_name, OCI8::::Unknown, true)
end

#describe_database(database_name) ⇒ Object

returns a OCI8::Metadata::Database.



2129
2130
2131
# File 'lib/oci8/metadata.rb', line 2129

def describe_database(database_name)
  __describe(database_name, OCI8::::Database, false)
end

#describe_function(function_name) ⇒ Object

returns a OCI8::Metadata::Function in the current schema.



2105
2106
2107
# File 'lib/oci8/metadata.rb', line 2105

def describe_function(function_name)
  __describe(function_name, OCI8::::Function, false)
end

#describe_package(package_name) ⇒ Object

returns a OCI8::Metadata::Package in the current schema.



2109
2110
2111
# File 'lib/oci8/metadata.rb', line 2109

def describe_package(package_name)
  __describe(package_name, OCI8::::Package, false)
end

#describe_procedure(procedure_name) ⇒ Object

returns a OCI8::Metadata::Procedure in the current schema.



2101
2102
2103
# File 'lib/oci8/metadata.rb', line 2101

def describe_procedure(procedure_name)
  __describe(procedure_name, OCI8::::Procedure, false)
end

#describe_schema(schema_name) ⇒ Object

returns a OCI8::Metadata::Schema in the database.



2125
2126
2127
# File 'lib/oci8/metadata.rb', line 2125

def describe_schema(schema_name)
  __describe(schema_name, OCI8::::Schema, false)
end

#describe_sequence(sequence_name) ⇒ Object

returns a OCI8::Metadata::Sequence in the current schema.



2121
2122
2123
# File 'lib/oci8/metadata.rb', line 2121

def describe_sequence(sequence_name)
  __describe(sequence_name, OCI8::::Sequence, false)
end

#describe_synonym(synonym_name, check_public_also = true) ⇒ Object

returns a OCI8::Metadata::Synonym in the current schema.



2117
2118
2119
# File 'lib/oci8/metadata.rb', line 2117

def describe_synonym(synonym_name, check_public_also = true)
  __describe(synonym_name, OCI8::::Synonym, check_public_also)
end

#describe_table(table_name, table_only = false) ⇒ Object

returns a OCI8::Metadata::Table or a OCI8::Metadata::View. If the name is a current schema’s synonym name or a public synonym name, it returns a OCI8::Metadata::Table or a OCI8::Metadata::View which the synonym refers.

If the second argument is true, this returns a OCI8::Metadata::Table in the current schema.



2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
# File 'lib/oci8/metadata.rb', line 2079

def describe_table(table_name, table_only = false)
  if table_only
    # check my own tables only.
    __describe(table_name, OCI8::::Table, false)
  else
    # check tables, views, synonyms and public synonyms.
     = __describe(table_name, OCI8::::Unknown, true)
    case 
    when OCI8::::Table, OCI8::::View
      
    when OCI8::::Synonym
      describe_table(.translated_name)
    else
      raise OCIError.new("ORA-04043: object #{table_name} does not exist", 4043)
    end
  end
end

#describe_type(type_name) ⇒ Object

returns a OCI8::Metadata::Type in the current schema.



2113
2114
2115
# File 'lib/oci8/metadata.rb', line 2113

def describe_type(type_name)
  __describe(type_name, OCI8::::Type, false)
end

#describe_view(view_name) ⇒ Object

returns a OCI8::Metadata::View in the current schema.



2097
2098
2099
# File 'lib/oci8/metadata.rb', line 2097

def describe_view(view_name)
  __describe(view_name, OCI8::::View, false)
end

#exec(sql, *bindvars, &block) ⇒ Object

Executes the sql statement. The type of return value depends on the type of sql statement: select; insert, update and delete; create, alter and drop; and PL/SQL.

When bindvars are specified, they are bound as bind variables before execution.

select statements without block

It returns the instance of OCI8::Cursor.

example:

conn = OCI8.new('scott', 'tiger')
cursor = conn.exec('SELECT * FROM emp')
while r = cursor.fetch()
  puts r.join(',')
end
cursor.close
conn.logoff

select statements with a block

It acts as iterator and returns the processed row counts. Fetched data is passed to the block as array. NULL value becomes nil in ruby.

example:

conn = OCI8.new('scott', 'tiger')
num_rows = conn.exec('SELECT * FROM emp') do |r|
  puts r.join(',')
end
puts num_rows.to_s + ' rows were processed.'
conn.logoff

PL/SQL block (ruby-oci8 1.0)

It returns the array of bind variables’ values.

example:

conn = OCI8.new('scott', 'tiger')
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123)
# => ["0123", 123]
conn.logoff

Above example uses two bind variables which names are :str and :num. These initial values are “the string whose width is 4 and whose value is ‘ABCD’” and “the number whose value is 123”. This method returns the array of these bind variables, which may modified by PL/SQL statement. The order of array is same with that of bind variables.

If a block is given, it is ignored.

PL/SQL block (ruby-oci8 2.0)

It returns the number of processed rows.

example:

conn = OCI8.new('scott', 'tiger')
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123)
# => 1
conn.logoff

If a block is given, the bind variables’ values are passed to the block after executed.

conn = OCI8.new('scott', 'tiger')
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123) do |str, num|
  puts str # => '0123'
  puts num # => 123
end
conn.logoff

FYI, the following code do same on ruby-oci8 1.0 and ruby-oci8 2.0.

conn.exec(sql, *bindvars) { |*outvars| outvars }

Other SQL statements

It returns the number of processed rows.

example:

conn = OCI8.new('scott', 'tiger')
num_rows = conn.exec('UPDATE emp SET sal = sal * 1.1')
puts num_rows.to_s + ' rows were updated.'
conn.logoff

example:

conn = OCI8.new('scott', 'tiger')
conn.exec('CREATE TABLE test (col1 CHAR(6))') # => 0
conn.logoff


241
242
243
244
# File 'lib/oci8/oci8.rb', line 241

def exec(sql, *bindvars, &block)
  @last_error = nil
  exec_internal(sql, *bindvars, &block)
end

#exec_internal(sql, *bindvars) ⇒ Object

same with OCI8#exec except that this doesn’t reset OCI8#last_error.



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/oci8/oci8.rb', line 247

def exec_internal(sql, *bindvars)
  begin
    cursor = parse(sql)
    ret = cursor.exec(*bindvars)
    case cursor.type
    when :select_stmt
      if block_given?
        cursor.fetch { |row| yield(row) }   # for each row
        ret = cursor.row_count()
      else
        ret = cursor
        cursor = nil # unset cursor to skip cursor.close in ensure block
        ret
      end
    when :begin_stmt, :declare_stmt # PL/SQL block
      if block_given?
        ary = []
        cursor.keys.sort.each do |key|
          ary << cursor[key]
        end
        yield(*ary)
      else
        ret
      end
    else
      ret # number of rows processed
    end
  ensure
    cursor.nil? || cursor.close
  end
end

#get_tdo_by_class(klass) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/oci8/object.rb', line 8

def get_tdo_by_class(klass)
  @id_to_tdo ||= {}
  @name_to_tdo ||= {}
  tdo = @name_to_tdo[klass.typename]
  return tdo if tdo

   = describe_any(klass.typename)
  if .is_a? OCI8::::Synonym
     = describe_any(.translated_name)
  end
  unless .is_a? OCI8::::Type
    raise "unknown typename #{klass.typename}"
  end
  OCI8::TDO.new(self, , klass)
end

#get_tdo_by_metadata(metadata) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/oci8/object.rb', line 24

def ()
  @id_to_tdo ||= {}
  @name_to_tdo ||= {}
  tdo = @id_to_tdo[.tdo_id]
  return tdo if tdo

  schema_name = .schema_name
  name = .name
  full_name = schema_name + '.' + name

  klass = OCI8::Object::Base.get_class_by_typename(full_name)
  klass = OCI8::Object::Base.get_class_by_typename(name) if klass.nil?
  if klass.nil?
    if schema_name == username
      eval "module Object\nclass \#{name.downcase.gsub(/(^|_)(.)/) { $2.upcase }} < OCI8::Object::Base\n  set_typename('\#{name}')\nend\nend\n"
      klass = OCI8::Object::Base.get_class_by_typename(name)
    else
      eval "module Object\nmodule \#{schema_name.downcase.gsub(/(^|_)(.)/) { $2.upcase }}\n  class \#{name.downcase.gsub(/(^|_)(.)/) { $2.upcase }} < OCI8::Object::Base\n    set_typename('\#{full_name}')\n  end\nend\nend\n"
      klass = OCI8::Object::Base.get_class_by_typename(full_name)
    end
  end
  OCI8::TDO.new(self, , klass)
end

#inspectObject



302
303
304
# File 'lib/oci8/oci8.rb', line 302

def inspect
  "#<OCI8:#{username}>"
end

#oracle_server_versionObject

:call-seq:

oracle_server_version -> oraver

Returns an OCI8::OracleVersion of the Oracle server version.

See also: OCI8.oracle_client_version



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/oci8/oci8.rb', line 312

def oracle_server_version
  unless defined? @oracle_server_version
    if vernum = oracle_server_vernum
      # If the Oracle client is Oracle 9i or upper,
      # get the server version from the OCI function OCIServerRelease.
      @oracle_server_version = OCI8::OracleVersion.new(vernum)
    else
      # Otherwise, get it from v$version.
      self.exec('select banner from v$version') do |row|
        if /^Oracle.*?(\d+\.\d+\.\d+\.\d+\.\d+)/ =~ row[0]
          @oracle_server_version = OCI8::OracleVersion.new($1)
          break
        end
      end
    end
  end
  @oracle_server_version
end

#parse(sql) ⇒ Object

call-seq:

parse(sql_text) -> an OCI8::Cursor

Returns a prepared SQL handle.



144
145
146
147
# File 'lib/oci8/oci8.rb', line 144

def parse(sql)
  @last_error = nil
  parse_internal(sql)
end

#parse_internal(sql) ⇒ Object

same with OCI8#parse except that this doesn’t reset OCI8#last_error.



150
151
152
153
154
# File 'lib/oci8/oci8.rb', line 150

def parse_internal(sql)
  cursor = OCI8::Cursor.new(self, sql)
  cursor.prefetch_rows = @prefetch_rows if @prefetch_rows
  cursor
end

#select_one(sql, *bindvars) ⇒ Object

:call-seq:

select_one(sql, *bindvars) -> first_one_row


282
283
284
285
286
287
288
289
290
291
# File 'lib/oci8/oci8.rb', line 282

def select_one(sql, *bindvars)
  cursor = self.parse(sql)
  begin
    cursor.exec(*bindvars)
    row = cursor.fetch
  ensure
    cursor.close
  end
  return row
end

#usernameObject



293
294
295
296
297
298
299
300
# File 'lib/oci8/oci8.rb', line 293

def username
  @username || begin
    exec('select user from dual') do |row|
      @username = row[0]
    end
    @username
  end
end