[ruby-oci8-commit] [349] trunk/ruby-oci8: * ext/oci8/oci8.c: revise rdoc comments for OCI8#ping and

nobody at rubyforge.org nobody at rubyforge.org
Mon May 18 12:49:30 EDT 2009


Revision: 349
Author:   kubo
Date:     2009-05-18 12:49:30 -0400 (Mon, 18 May 2009)

Log Message:
-----------
* ext/oci8/oci8.c: revise rdoc comments for OCI8#ping and
    OCI8#client_identifier=. Add OCI8#module=, OCI8#action= and
    OCI8#client_info.
* test/test_appinfo.rb: add test cases for OCI8#module=,
    OCI8#action= and OCI8#client_info.

Modified Paths:
--------------
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/ext/oci8/oci8.c
    trunk/ruby-oci8/test/test_appinfo.rb

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2009-05-17 13:07:16 UTC (rev 348)
+++ trunk/ruby-oci8/ChangeLog	2009-05-18 16:49:30 UTC (rev 349)
@@ -1,3 +1,10 @@
+2009-05-18  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/oci8.c: revise rdoc comments for OCI8#ping and
+	    OCI8#client_identifier=. Add OCI8#module=, OCI8#action= and
+	    OCI8#client_info.
+	* test/test_appinfo.rb: add test cases for OCI8#module=,
+	    OCI8#action= and OCI8#client_info.
+
 2009-05-17  KUBO Takehiro  <kubo at jiubao.org>
 	* NEWS: add changes between 2.0.1 and 2.0.2.
 	* VERSION: change version to 2.0.2.

Modified: trunk/ruby-oci8/ext/oci8/oci8.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.c	2009-05-17 13:07:16 UTC (rev 348)
+++ trunk/ruby-oci8/ext/oci8/oci8.c	2009-05-18 16:49:30 UTC (rev 349)
@@ -564,13 +564,15 @@
  * call-seq:
  *   ping -> true or false
  *
- * Verifies that the Oracle connection is alive.
+ * Makes a round trip call to the server to confirm that the connection and
+ * the server are active.
  *
  * OCI8#ping also can be used to flush all the pending OCI client-side calls
- * to the server if any exist. See: OCI8#client_identifier=.
+ * to the server if any exist.
  *
  * For Oracle 10.2 client or upper, a dummy round trip call is made by a newly
- * added OCI function in Oracle 10.2.
+ * added OCI function OCIPing[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci16msc007.htm#sthref3540]
+ * in Oracle 10.2.
  *
  * For Oracle 10.1 client or lower, a simple PL/SQL block "BEGIN NULL; END;"
  * is executed to make a round trip call.
@@ -592,21 +594,29 @@
 
 /*
  * call-seq:
- *   client_identifier = string
+ *   client_identifier = string or nil
  *
- * Sets the CLIENT_IDENTIFIER column in the V$SESSION dictionary view.
- * This can be up to 64 bytes long. The first character should not be ':'.
+ * This is equivalent to the following PL/SQL block.
  *
- * If the Oracle client is 9i or upper, the change is not reflected to the
- * server immediately. It is postponed until the next round trip call for
- * example OCI8#exec, OCI8#ping, etc.
+ *   BEGIN
+ *     DBMS_SESSION.SET_IDENTIFIER(:client_id);
+ *   END;
  *
- * This call is equivalent to "DBMS_SESSION.SET_IDENTIFIER(client_id VARCHAR2);"
- * and available when the server is Oracle 9i or upper.
+ * If the Oracle client is 9i or upper, this doesn't perform network
+ * round trips. The change is reflected to the server by the next round
+ * trip such as OCI8#exec, OCI8#ping, etc. This means that you can
+ * reduce one SQL execution to set client identifier.
+ *
+ * As for Oracle 8i client or lower, this method executes the PL/SQL
+ * block internally.
+ *
+ * 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]
+ *
+ * Note: The Oracle server must be 9i or upper to use this method.
+ *
  */
 static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
 {
-    OCISession *sess = oci8_get_oci_session(self);
     char *ptr;
     ub4 size;
 
@@ -618,11 +628,11 @@
         ptr = "";
         size = 0;
     }
-    if (oracle_client_version >= 900) {
+    if (oracle_client_version >= ORAVER_9_0) {
         if (size > 0 && ptr[0] == ':') {
             rb_raise(rb_eArgError, "client identifier should not start with ':'.");
         }
-        oci_lc(OCIAttrSet(sess, OCI_HTYPE_SESSION, ptr,
+        oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
                           size, OCI_ATTR_CLIENT_IDENTIFIER, oci8_errhp));
     } else {
         oci8_exec_sql_var_t bind_vars[1];
@@ -634,11 +644,190 @@
         bind_vars[0].indp = NULL;
         bind_vars[0].alenp = NULL;
 
-        oci8_exec_sql(oci8_get_svcctx(self), "BEGIN DBMS_SESSION.SET_IDENTIFIER(:client_id); END;", 0, NULL, 1, bind_vars, 1);
+        oci8_exec_sql(oci8_get_svcctx(self),
+                      "BEGIN\n"
+                      "  DBMS_SESSION.SET_IDENTIFIER(:client_id);\n"
+                      "END;\n", 0, NULL, 1, bind_vars, 1);
     }
     return val;
 }
 
+/*
+ * call-seq:
+ *   module = string or nil
+ *
+ * This is equivalent to the following PL/SQL block.
+ *
+ *   DECLARE
+ *     action VARCHAR2(32);
+ *   BEGIN
+ *     -- retrieve action name.
+ *     SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;
+ *     -- change module name without modifying the action name.
+ *     DBMS_APPLICATION_INFO.SET_MODULE(:module, action);
+ *   END;
+ *
+ * If the Oracle client is 10g or upper, this doesn't perform network
+ * round trips. The change is reflected to the server by the next round
+ * trip such as OCI8#exec, OCI8#ping, etc. This means that you can
+ * reduce one SQL execution to set module name.
+ *
+ * As for Oracle 9i client or lower, this method executes the PL/SQL
+ * block internally.
+ *
+ * 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#i996826]
+ */
+static VALUE oci8_set_module(VALUE self, VALUE val)
+{
+    char *ptr;
+    ub4 size;
+
+    if (!NIL_P(val)) {
+        OCI8SafeStringValue(val);
+        ptr = RSTRING_PTR(val);
+        size = RSTRING_LEN(val);
+    } else {
+        ptr = "";
+        size = 0;
+    }
+    if (oracle_client_version >= ORAVER_10_1) {
+        /* Oracle 10g or upper */
+        oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
+                          size, OCI_ATTR_MODULE, oci8_errhp));
+    } else {
+        /* Oracle 9i or lower */
+        oci8_exec_sql_var_t bind_vars[1];
+
+        /* :module */
+        bind_vars[0].valuep = ptr;
+        bind_vars[0].value_sz = size;
+        bind_vars[0].dty = SQLT_CHR;
+        bind_vars[0].indp = NULL;
+        bind_vars[0].alenp = NULL;
+
+        oci8_exec_sql(oci8_get_svcctx(self),
+                      "DECLARE\n"
+                      "  action VARCHAR2(32);\n"
+                      "BEGIN\n"
+                      "  SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;\n"
+                      "  DBMS_APPLICATION_INFO.SET_MODULE(:module, action);\n"
+                      "END;\n", 0, NULL, 1, bind_vars, 1);
+    }
+    return self;
+}
+
+/*
+ * call-seq:
+ *   action = string or nil
+ *
+ * This is equivalent to the following PL/SQL block.
+ *
+ *   BEGIN
+ *     DBMS_APPLICATION_INFO.SET_ACTION(:action);
+ *   END;
+ *
+ * If the Oracle client is 10g or upper, this doesn't perform network
+ * round trips. The change is reflected to the server by the next round
+ * trip such as OCI8#exec, OCI8#ping, etc. This means that you can
+ * reduce one SQL execution to set action name.
+ *
+ * As for Oracle 9i client or lower, this method executes the PL/SQL
+ * block internally.
+ *
+ * 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]
+ */
+static VALUE oci8_set_action(VALUE self, VALUE val)
+{
+    char *ptr;
+    ub4 size;
+
+    if (!NIL_P(val)) {
+        OCI8SafeStringValue(val);
+        ptr = RSTRING_PTR(val);
+        size = RSTRING_LEN(val);
+    } else {
+        ptr = "";
+        size = 0;
+    }
+    if (oracle_client_version >= ORAVER_10_1) {
+        /* Oracle 10g or upper */
+        oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
+                          size, OCI_ATTR_ACTION, oci8_errhp));
+    } else {
+        /* Oracle 9i or lower */
+        oci8_exec_sql_var_t bind_vars[1];
+
+        /* :action */
+        bind_vars[0].valuep = ptr;
+        bind_vars[0].value_sz = size;
+        bind_vars[0].dty = SQLT_CHR;
+        bind_vars[0].indp = NULL;
+        bind_vars[0].alenp = NULL;
+
+        oci8_exec_sql(oci8_get_svcctx(self),
+                      "BEGIN\n"
+                      "  DBMS_APPLICATION_INFO.SET_ACTION(:action);\n"
+                      "END;\n", 0, NULL, 1, bind_vars, 1);
+    }
+    return val;
+}
+
+/*
+ * call-seq:
+ *   client_info = string or nil
+ *
+ * This is equivalent to the following PL/SQL block.
+ *
+ *   BEGIN
+ *     DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:client_info);
+ *   END;
+ *
+ * If the Oracle client is 10g or upper, this doesn't perform network
+ * round trips. The change is reflected to the server by the next round
+ * trip such as OCI8#exec, OCI8#ping, etc. This means that you can
+ * reduce one SQL execution to set client info.
+ *
+ * As for Oracle 9i client or lower, this method executes the PL/SQL
+ * block internally.
+ *
+ * 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]
+ */
+static VALUE oci8_set_client_info(VALUE self, VALUE val)
+{
+    char *ptr;
+    ub4 size;
+
+    if (!NIL_P(val)) {
+        OCI8SafeStringValue(val);
+        ptr = RSTRING_PTR(val);
+        size = RSTRING_LEN(val);
+    } else {
+        ptr = "";
+        size = 0;
+    }
+    if (oracle_client_version >= ORAVER_10_1) {
+        /* Oracle 10g or upper */
+        oci_lc(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, ptr,
+                          size, OCI_ATTR_CLIENT_INFO, oci8_errhp));
+    } else {
+        /* Oracle 9i or lower */
+        oci8_exec_sql_var_t bind_vars[1];
+
+        /* :client_info */
+        bind_vars[0].valuep = ptr;
+        bind_vars[0].value_sz = size;
+        bind_vars[0].dty = SQLT_CHR;
+        bind_vars[0].indp = NULL;
+        bind_vars[0].alenp = NULL;
+
+        oci8_exec_sql(oci8_get_svcctx(self), 
+                      "BEGIN\n"
+                      "  DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:client_info);\n"
+                      "END;\n", 0, NULL, 1, bind_vars, 1);
+    }
+    return val;
+}
+
 VALUE Init_oci8(void)
 {
     cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_class);
@@ -674,6 +863,9 @@
     rb_define_private_method(cOCI8, "oracle_server_vernum", oci8_oracle_server_vernum, 0);
     rb_define_method(cOCI8, "ping", oci8_ping, 0);
     rb_define_method(cOCI8, "client_identifier=", oci8_set_client_identifier, 1);
+    rb_define_method(cOCI8, "module=", oci8_set_module, 1);
+    rb_define_method(cOCI8, "action=", oci8_set_action, 1);
+    rb_define_method(cOCI8, "client_info=", oci8_set_client_info, 1);
     return cOCI8;
 }
 

Modified: trunk/ruby-oci8/test/test_appinfo.rb
===================================================================
--- trunk/ruby-oci8/test/test_appinfo.rb	2009-05-17 13:07:16 UTC (rev 348)
+++ trunk/ruby-oci8/test/test_appinfo.rb	2009-05-18 16:49:30 UTC (rev 349)
@@ -23,6 +23,34 @@
     assert_nil(@conn.select_one("SELECT SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER') FROM DUAL")[0]);
   end
 
+  def test_set_module
+    # set module
+    @conn.module = 'ruby-oci8'
+    assert_equal('ruby-oci8', @conn.select_one("SELECT SYS_CONTEXT('USERENV', 'MODULE') FROM DUAL")[0]);
+    # clear module
+    @conn.module = nil
+    assert_nil(@conn.select_one("SELECT SYS_CONTEXT('USERENV', 'MODULE') FROM DUAL")[0]);
+  end
+
+  def test_set_action
+    # set action
+    @conn.action = 'test_set_action'
+    assert_equal('test_set_action', @conn.select_one("SELECT SYS_CONTEXT('USERENV', 'ACTION') FROM DUAL")[0]);
+    # clear action
+    @conn.action = nil
+    assert_nil(@conn.select_one("SELECT SYS_CONTEXT('USERENV', 'ACTION') FROM DUAL")[0]);
+  end
+
+  def test_set_client_info
+    # set client_info
+    client_info = "ruby-oci8:#{Process.pid()}"
+    @conn.client_info = client_info
+    assert_equal(client_info, @conn.select_one("SELECT SYS_CONTEXT('USERENV', 'CLIENT_INFO') FROM DUAL")[0]);
+    # clear client_info
+    @conn.client_info = nil
+    assert_nil(@conn.select_one("SELECT SYS_CONTEXT('USERENV', 'CLIENT_INFO') FROM DUAL")[0]);
+  end
+
   def teardown
     @conn.logoff
   end




More information about the ruby-oci8-commit mailing list