]> granicus.if.org Git - php/commitdiff
Add Oracle PL/SQL BOOLEAN type support to oci_bind_by_name()
authorChristopher Jones <sixd@php.net>
Mon, 10 Feb 2014 23:00:42 +0000 (15:00 -0800)
committerChristopher Jones <sixd@php.net>
Mon, 10 Feb 2014 23:00:42 +0000 (15:00 -0800)
ext/oci8/oci8.c
ext/oci8/oci8_statement.c
ext/oci8/package.xml
ext/oci8/php_oci8.h
ext/oci8/tests/bind_boolean_1.phpt [new file with mode: 0644]
ext/oci8/tests/error_bind_2.phpt [new file with mode: 0644]
ext/oci8/tests/error_bind_3.phpt [new file with mode: 0644]

index c3ca7a817204f9a843e1bf8cf00753409718b0f9..a890c94dabeb0d73876d5fe297cda5c0d26ae38a 100644 (file)
@@ -26,8 +26,6 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id$ */
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -1251,6 +1249,9 @@ PHP_MINIT_FUNCTION(oci)
        REGISTER_LONG_CONSTANT("SQLT_BDOUBLE",SQLT_BDOUBLE, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("SQLT_BFLOAT",SQLT_BFLOAT, CONST_CS | CONST_PERSISTENT);
 #endif
+#if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
+       REGISTER_LONG_CONSTANT("SQLT_BOL",SQLT_BOL, CONST_CS | CONST_PERSISTENT);
+#endif
 
        REGISTER_LONG_CONSTANT("OCI_B_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("SQLT_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
@@ -1265,6 +1266,9 @@ PHP_MINIT_FUNCTION(oci)
        REGISTER_LONG_CONSTANT("OCI_B_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("OCI_B_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("OCI_B_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
+#if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
+       REGISTER_LONG_CONSTANT("OCI_B_BOL",SQLT_BOL, CONST_CS | CONST_PERSISTENT);
+#endif
 
 /* for OCIFetchStatement */
        REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_COLUMN", PHP_OCI_FETCHSTATEMENT_BY_COLUMN, CONST_CS | CONST_PERSISTENT);
index 56882cf908b8172af8f79d544238e2df9fc68503..520809c81d2bb30d7e2da27e9698b08cf155880a 100644 (file)
@@ -928,19 +928,16 @@ int php_oci_bind_pre_exec(void *data, void *result TSRMLS_DC)
                        }
                        break;
                        
+               case SQLT_CHR:
+               case SQLT_AFC:
                case SQLT_INT:
                case SQLT_NUM:
-                       if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
-                               *(int *)result = 1;
-                       }
-                       break;
-                       
+#if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
+               case SQLT_BOL:
+#endif
                case SQLT_LBI:
                case SQLT_BIN:
                case SQLT_LNG:
-               case SQLT_AFC:
-               case SQLT_CHR:
                        if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
                                *(int *)result = 1;
@@ -955,7 +952,7 @@ int php_oci_bind_pre_exec(void *data, void *result TSRMLS_DC)
                        break;
        }
 
-       /* reset all bind stuff to a normal state..-. */
+       /* reset all bind stuff to a normal state... */
        bind->indicator = 0;
 
        return 0;
@@ -1185,6 +1182,20 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len,
                        }
                        break;
 
+#if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
+               case SQLT_BOL:
+                       if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
+                               return 1;
+                       }
+                       convert_to_boolean(var);
+                       bind_data = (int *)&Z_LVAL_P(var);
+                       value_sz = sizeof(int);
+
+                       mode = OCI_DEFAULT;
+                       break;
+#endif
+
                default:
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %d", (int)type);
                        return 1;
index 8e55b9abd5c3ccfa88566c1153423981de27c51e..d81d896f1357193e31098e998c8b1243bd9e6b43 100644 (file)
@@ -45,7 +45,7 @@ libraries are available.
   <active>no</active>
  </lead>
 
- <date>2013-10-22</date>
+ <date>2014-02-10</date>
  <time>12:00:00</time>
 
   <version>
@@ -58,7 +58,8 @@ libraries are available.
   </stability>
   <license uri="http://www.php.net/license">PHP</license>
   <notes>
-    Build change: Fix source variable definition for C89 compatibility
+Added oci_bind_by_name() support for PL/SQL BOOLEAN type    
+Build change: Fix source variable definition for C89 compatibility
   </notes>
  <contents>
   <dir name="/">
@@ -91,6 +92,7 @@ libraries are available.
     <file name="b47243_1.phpt" role="test" />
     <file name="b47243_2.phpt" role="test" />
     <file name="b47243_3.phpt" role="test" />
+    <file name="bind_boolean_1.phpt" role="test" />
     <file name="bind_char_1_11gR1.phpt" role="test" />
     <file name="bind_char_1.phpt" role="test" />
     <file name="bind_char_2_11gR1.phpt" role="test" />
@@ -268,6 +270,8 @@ libraries are available.
     <file name="error2.phpt" role="test" />
     <file name="error3.phpt" role="test" />
     <file name="error_bind.phpt" role="test" />
+    <file name="error_bind_2.phpt" role="test" />
+    <file name="error_bind_3.phpt" role="test" />
     <file name="error_old.phpt" role="test" />
     <file name="error_parse.phpt" role="test" />
     <file name="error.phpt" role="test" />
index 63924eca01053492d78d1c2d7dc8354a73098f53..17061066d2dcaccf0969b06a64720e2483efce72 100644 (file)
@@ -45,7 +45,7 @@
  */
 #undef PHP_OCI8_VERSION
 #endif
-#define PHP_OCI8_VERSION "2.0.7-dev"
+#define PHP_OCI8_VERSION "2.0.7"
 
 extern zend_module_entry oci8_module_entry;
 #define phpext_oci8_ptr &oci8_module_entry
diff --git a/ext/oci8/tests/bind_boolean_1.phpt b/ext/oci8/tests/bind_boolean_1.phpt
new file mode 100644 (file)
index 0000000..49ac03c
--- /dev/null
@@ -0,0 +1,138 @@
+--TEST--
+Basic PL/SQL "BOOLEAN" (SQLT_BOL) bind test
+--SKIPIF--
+<?php 
+if (!extension_loaded('oci8')) die ("skip no oci8 extension"); 
+require(dirname(__FILE__).'/connect.inc');
+preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches);
+if (!(isset($matches[0]) && $matches[1] >= 12)) {
+    die("skip expected output only valid when using Oracle Database 12c or greater");
+}
+preg_match('/^[[:digit:]]+/', oci_client_version(), $matches);
+if (!(isset($matches[0]) && $matches[0] >= 12)) { 
+    die("skip works only with Oracle 12c or greater version of Oracle client libraries");
+}
+?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+// Run Test
+
+echo "Test 1\n";
+
+$sql = "begin
+        :output1 := true;
+        :output2 := false;
+       end;";
+
+$s = oci_parse($c, $sql);
+oci_bind_by_name($s, ':output1', $output1, -1, OCI_B_BOL);
+oci_bind_by_name($s, ':output2', $output2, -1, OCI_B_BOL);
+oci_execute($s);
+var_dump($output1);
+var_dump($output2);
+
+echo "Test 2\n";
+
+$b = "abc";  // bind var type will change
+$sql = "begin :b := true; end;";
+$s = oci_parse($c, $sql);
+oci_bind_by_name($s, ':b', $b, -1, OCI_B_BOL);
+oci_execute($s);
+var_dump($b);
+
+
+echo "Test 3\n";
+
+$sql = 
+    "begin
+    if (:input < 10) then
+        :output := true;
+    else
+        :output := false;
+    end if;
+end;";
+$s = oci_parse($c, $sql);
+oci_bind_by_name($s, ':output', $output, -1, OCI_B_BOL);
+for ($input = 5; $input < 15; ++$input) {
+    oci_bind_by_name($s, ':input', $input);
+    oci_execute($s);
+    var_dump($output);
+}
+
+echo "Test 4\n";
+
+$sql = 
+"begin
+  if (mod(:userid,2) = 0) then
+    :b := true;
+  else
+    :b := false;
+  end if;
+end;";
+$s = oci_parse($c, $sql);
+oci_bind_by_name($s, ':b', $b, -1, OCI_B_BOL);
+for ($userid = 1; $userid <= 10; ++$userid) {
+    oci_bind_by_name($s, ':userid', $userid, -1, SQLT_INT);
+    oci_execute($s);
+    var_dump($b);
+}
+
+echo "Test 5\n";
+
+$sql = 
+"declare
+  l boolean;
+begin
+  l := :b1;
+  :b1 := :b2;
+  :b2 := l;
+end;";
+$s = oci_parse($c, $sql);
+$b1 = true;
+$b2 = false;
+var_dump($b1, $b2);
+oci_bind_by_name($s, ':b1', $b1, -1, OCI_B_BOL);
+oci_bind_by_name($s, ':b2', $b2, -1, OCI_B_BOL);
+oci_execute($s);
+var_dump($b1, $b2);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Test 1
+bool(true)
+bool(false)
+Test 2
+bool(true)
+Test 3
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+Test 4
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+Test 5
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+===DONE===
diff --git a/ext/oci8/tests/error_bind_2.phpt b/ext/oci8/tests/error_bind_2.phpt
new file mode 100644 (file)
index 0000000..6427168
--- /dev/null
@@ -0,0 +1,63 @@
+--TEST--
+Test some more oci_bind_by_name error conditions
+--SKIPIF--
+<?php 
+if (!extension_loaded('oci8')) die ("skip no oci8 extension"); 
+$target_dbs = array('oracledb' => true, 'timesten' => true);  // test runs on these DBs
+require(dirname(__FILE__).'/skipif.inc');
+preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches);
+if (!(isset($matches[0]) && $matches[1] >= 12)) {
+    die("skip expected output only valid when using Oracle Database 12c or greater");
+}
+preg_match('/^[[:digit:]]+/', oci_client_version(), $matches);
+if (!(isset($matches[0]) && $matches[0] >= 12)) { 
+    die("skip works only with Oracle 12c or greater version of Oracle client libraries");
+}
+?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+// Initialization
+
+$stmtarray = array(
+    "drop table error_bind_2_tab",
+    "create table error_bind_2_tab(name varchar(10))"
+);
+oci8_test_sql_execute($c, $stmtarray);
+
+echo "Test 1 - SQLT_BOL\n";
+
+unset($name);
+$stmt = oci_parse($c, "insert into error_bind_2_tab values (:name)");
+oci_bind_by_name($stmt, ":name", $name, -1, SQLT_BOL);
+$name=$c;
+var_dump(oci_execute($stmt));
+
+echo "Test 2 - SQLT_BOL\n";
+
+unset($name);
+$stmt = oci_parse($c, "insert into error_bind_2_tab values (:name)");
+$name=$c;
+oci_bind_by_name($stmt, ":name", $name, -1, SQLT_BOL);
+
+// Clean up
+
+$stmtarray = array(
+    "drop table error_bind_2_tab",
+);
+oci8_test_sql_execute($c, $stmtarray);
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Test 1 - SQLT_BOL
+
+Warning: oci_execute(): Invalid variable used for bind in %s on line %d
+bool(false)
+Test 2 - SQLT_BOL
+
+Warning: oci_bind_by_name(): Invalid variable used for bind in %s on line %d
+Done
diff --git a/ext/oci8/tests/error_bind_3.phpt b/ext/oci8/tests/error_bind_3.phpt
new file mode 100644 (file)
index 0000000..7522dfe
--- /dev/null
@@ -0,0 +1,48 @@
+--TEST--
+Test some more oci_bind_by_name error conditions
+--SKIPIF--
+<?php 
+if (!extension_loaded('oci8')) die ("skip no oci8 extension"); 
+$target_dbs = array('oracledb' => true, 'timesten' => true);  // test runs on these DBs
+require(dirname(__FILE__).'/skipif.inc');
+preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches);
+if (!(isset($matches[0]) && $matches[1] >= 12)) {
+    die("skip expected output only valid when using Oracle Database 12c or greater");
+}
+preg_match('/^[[:digit:]]+/', oci_client_version(), $matches);
+if (!(isset($matches[0]) && $matches[0] >= 12)) { 
+    die("skip works only with Oracle 12c or greater version of Oracle client libraries");
+}
+?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+$sql = "begin
+        :output1 := 99;
+        :output2 := 'abc';
+       end;";
+
+$s = oci_parse($c, $sql);
+oci_bind_by_name($s, ':output1', $output1, -1, OCI_B_BOL);
+oci_bind_by_name($s, ':output2', $output2, -1, OCI_B_BOL);
+oci_execute($s);
+var_dump($output1);
+var_dump($output2);
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Warning: oci_execute(): ORA-06550: line %d, column %d:
+PLS-00382: %s
+ORA-06550: line %d, column %d:
+PL/SQL: %s
+ORA-06550: line %d, column %d:
+PLS-00382: %s
+ORA-06550: line %d, column %d:
+PL/SQL: %s in %s on line %d
+bool(false)
+bool(false)
+Done