Author: byterock
Date: Tue Jan 19 10:35:30 2010
New Revision: 13746

Modified:
   dbd-oracle/trunk/Oracle.pm
   dbd-oracle/trunk/t/58object.t

Log:
a new patch from Charles Jardine  for testing objects and some clean up on the 
pod

Modified: dbd-oracle/trunk/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/Oracle.pm  (original)
+++ dbd-oracle/trunk/Oracle.pm  Tue Jan 19 10:35:30 2010
@@ -1478,11 +1478,12 @@
 =item ora_ncs_buff_mtpl
 
 You can now customize the size of the buffer when selecting LOBs with
-the built in AUTO Lob.  The default value is 1 which should be fine
-for most situations. If you are converting between a NCS on the DB and
-one on the Client then you might want to set this to 2.  The orignal
-value (prior to version 1.24) of 4 was found to be excessive.  For
-convenience I have added support for a 'ORA_DBD_NCS_BUFFER'
+the built in AUTO Lob.  The default value is 4 which should is actully 
exessive 
+for most situations but is needed for backward compatibilty. 
+If you not converting between a NCS on the DB and the Client then you might 
+want to set this to 1 to free up memory.  
+
+For convenience I have added support for a 'ORA_DBD_NCS_BUFFER'
 environment variable that you can use at the OS level to set this
 value.  If used it will take the value at the connect stage.
 
@@ -3145,38 +3146,6 @@
 The maximum value of 'LongReadLen' seems to be dependant on the physical 
memory limits of the box that Oracle is running on.  You have most likely 
reached this limit if you run into
 an 'ORA-01062: unable to allocate memory for define buffer' error.  One 
solution is to set the size of 'LongReadLen' to a lower value. 
 
-When getting CLOBs and NCLOBs in or out of Oracle ,the Server will translate 
from the Server's NCharSet to the
-Client's. If they happen to be the same or at least compatable then all of 
these actions are a 1 char to 1 char bases. Thus if you set your LongReadLen 
-buffer to 10_000_000 you will get up to 10_000_000 char. 
-
-However if the Server has to translate from one NCharSet to another it will 
use bytes for conversion. In versions 
-earlier than 1.24 this buffer was always 4 * LONG_READ_LEN which was very 
wasteful so you might of asking for only 
-10_000_000 bytes but you were actually using 40_000_000 bytes under the hood.  
You would still get 10_000_000 bytes (maybe less characters though) but 
-you are using allot more memory that you need.
-
-You can now customize the size of the buffer by setting the 
'ora_ncs_buff_mtpl' either on the connection or statement handle. You can
-also set this as 'ORA_DBD_NCS_BUFFER' OS environment variable so you will have 
to go back and change all your code if you are getting into trouble.
-
-The default value is set to 4 for backward compatiblty. You can lower this 
value and thus increase the amount of data you can retreive. If the
-ora_ncs_buff_mtpl is too small DBD::Oracle will thow and error telling you to 
increase this buffer by one.
-
-If the error is not captured then you may get 
-
-  ORA-03127: no new operations allowed until the active operation ends
-  
-which is one of the more obscure ORA errors (have some fun and report it to 
Meta-Link they will scratch their heads for hours) at some random point later 
on,
-usually at a finish() or disconnect() or even a fetch().
-
-If you get this, simply increment the ora_ncs_buff_mtpl by one until it goes 
away.
-
-This should greatly increase your ability to select very large CLOBs or 
NCLOBs, by freeing up a large block of menory.
-
-You can tune this value by setting ora_oci_success_warn which will display the 
following
-
-  OCILobRead field 2 of 3 SUCCESS: csform 1 (SQLCS_IMPLICIT), LOBlen 
10240(characters), LongReadLen 20(characters), BufLen 80(characters), Got 
28(characters)
-
-In the case above we Got 28 characters (well really only 20 characters of 28 
bytes) so we could use ora_ncs_buff_mtpl=>2 (20*2=40) thus saving 40bytes of 
memory.
-
 For example give this table;
 
   CREATE TABLE test_long (
@@ -3200,6 +3169,40 @@
   
 before the execute will return all the long1 fields but they will be truncated 
at 2MBs. 
 
+=head3 Using ora_ncs_buff_mtpl
+
+When getting CLOBs and NCLOBs in or out of Oracle, the Server will translate 
from the Server's NCharSet to the
+Client's. If they happen to be the same or at least compatable then all of 
these actions are a 1 char to 1 char bases. 
+Thus if you set your LongReadLen buffer to 10_000_000 you will get up to 
10_000_000 char. 
+
+However if the Server has to translate from one NCharSet to another it will 
use bytes for conversion. The buffer 
+value is set to 4 * LONG_READ_LEN which was very wasteful as you might only be 
asking for 10_000_000 bytes 
+but you were actually using 40_000_000 bytes of buffer under the hood.  You 
would still get 10_000_000 bytes
+(maybe less characters though) but you are using allot more memory that you 
need.
+
+You can now customize the size of the buffer by setting the 
'ora_ncs_buff_mtpl' either on the connection or statement handle. You can
+also set this as 'ORA_DBD_NCS_BUFFER' OS environment variable so you will have 
to go back and change all your code if you are getting into trouble.
+
+The default value is still set to 4 for backward compatiblty. You can lower 
this value and thus increase the amount of data you can retreive. If the
+ora_ncs_buff_mtpl is too small DBD::Oracle will thow and error telling you to 
increase this buffer by one.
+
+If the error is not captured then you may get at some random point later on, 
usually at a finish() or disconnect() or even a fetch() this error;
+
+  ORA-03127: no new operations allowed until the active operation ends
+  
+This is one of the more obscure ORA errors (have some fun and report it to 
Meta-Link they will scratch their heads for hours) 
+
+If you get this, simply increment the ora_ncs_buff_mtpl by one until it goes 
away.
+
+This should greatly increase your ability to select very large CLOBs or 
NCLOBs, by freeing up a large block of menory.
+
+You can tune this value by setting ora_oci_success_warn which will display the 
following
+
+  OCILobRead field 2 of 3 SUCCESS: csform 1 (SQLCS_IMPLICIT), LOBlen 
10240(characters), LongReadLen 20(characters), BufLen 80(characters), Got 
28(characters)
+
+In the case above the query Got 28 characters (well really only 20 characters 
of 28 bytes) so we could use ora_ncs_buff_mtpl=>2 (20*2=40) thus saving 40bytes 
of memory.
+
+
 =head3 Simple Fetch for CLOBs and BLOBs
 
 To use this interface for CLOBs and LOBs datatypes set the 'ora_pers_lob' 
attribute of the statement handle to '1' with the prepare method, as well

Modified: dbd-oracle/trunk/t/58object.t
==============================================================================
--- dbd-oracle/trunk/t/58object.t       (original)
+++ dbd-oracle/trunk/t/58object.t       Tue Jan 19 10:35:30 2010
@@ -5,7 +5,7 @@
 use strict;

 use Data::Dumper;

 

-use Test::More tests => 35;

+use Test::More tests => 51;

 unshift @INC ,'t';

 require 'nchar_test_lib.pl';

 

@@ -46,9 +46,16 @@
 my $super_type = "${obj_prefix}_type_A";

 my $sub_type = "${obj_prefix}_type_B";

 my $table = "${obj_prefix}_obj_table";

+my $outer_type = "${obj_prefix}_outer_type";

+my $inner_type = "${obj_prefix}_inner_type";

+my $list_type = "${obj_prefix}_list_type";

+my $nest_table = "${obj_prefix}_nest_table";

+my $list_table = "${obj_prefix}_list_table";

 

 sub drop_test_objects {

-    for my $obj ("TABLE $table", "TYPE $sub_type", "TYPE $super_type") {

+    for my $obj ("TABLE $list_table", "TABLE $nest_table",

+                 "TYPE $list_type", "TYPE $outer_type", "TYPE $inner_type",

+                 "TABLE $table", "TYPE $sub_type", "TYPE $super_type") {

         #do not warn if already there

         eval {

             local $dbh->{PrintError} = 0;

@@ -79,6 +86,30 @@
 $dbh->do(qq{ INSERT INTO $table VALUES (3, $sub_type(5, 'obj3', NULL, 
777.666)) }

             ) or die $dbh->errstr;

 

+$dbh->do(qq{ CREATE OR REPLACE TYPE $inner_type AS OBJECT (

+                num     INTEGER,

+                name    VARCHAR2(20)

+            ) FINAL }) or die $dbh->errstr;

+$dbh->do(qq{ CREATE OR REPLACE TYPE $outer_type AS OBJECT (

+                num     INTEGER,

+                obj     $inner_type

+            ) FINAL }) or die $dbh->errstr;

+$dbh->do(qq{ CREATE OR REPLACE TYPE $list_type AS

+                            TABLE OF $inner_type }) or die $dbh->errstr;

+$dbh->do(qq{ CREATE TABLE $nest_table(obj $outer_type) }) or die $dbh->errstr;

+$dbh->do(qq{ INSERT INTO $nest_table VALUES($outer_type(91, $inner_type(1, 
'one'))) }

+            ) or die $dbh->errstr;

+$dbh->do(qq{ INSERT INTO $nest_table VALUES($outer_type(92, $inner_type(0, 
null))) }

+            ) or die $dbh->errstr;

+$dbh->do(qq{ INSERT INTO $nest_table VALUES($outer_type(93, null)) }

+            ) or die $dbh->errstr;

+

+$dbh->do(qq{ CREATE TABLE $list_table ( id INTEGER, list $list_type )

+               NESTED TABLE list STORE AS ${list_table}_list }) or die 
$dbh->errstr;

+$dbh->do(qq{ INSERT INTO $list_table VALUES(81,$list_type($inner_type(null, 
'listed'))) }

+            ) or die $dbh->errstr;

+

+

 # Test old (backward compatible) interface 

 

 # test select testing objects 

@@ -152,6 +183,42 @@
 is_deeply($obj->attr, $expected_hash, 'DBD::Oracle::Object->attr');

 is($obj->attr("NAME"), 'obj3', 'DBD::Oracle::Object->attr("NAME")');

 

+# try the list table

+$sth = $dbh->prepare("select * from $list_table");

+ok ($sth, 'new: Prepare select with nested table of objects');

+ok ($sth->execute(), 'new: Execute (nested table)');

+

+...@row1 = $sth->fetchrow();

+ok (scalar @row1, 'new: Fetch first row (nested table)');

+is_deeply($row1[1]->[0]->attr, {NUM=>undef, NAME=>'listed'},

+           'Check propertes of first (and only) item in nested table');

+

+ok (!$sth->fetchrow(), 'new: No more rows expected (nested table)');

+

+#try the nested table

+$sth = $dbh->prepare("select * from $nest_table");

+ok ($sth, 'new: Prepare select with nested object');

+ok ($sth->execute(), 'new: Execute (nested object)');

+

+...@row1 = $sth->fetchrow();

+ok (scalar @row1, 'new: Fetch first row (nested object)');

+is($row1[0]->attr->{NUM}, '91', 'Check obj.num');

+is_deeply($row1[0]->attr->{OBJ}->attr, {NUM=>'1', NAME=>'one'}, 'Check 
obj.obj');

+

+...@row2 = $sth->fetchrow();

+ok (scalar @row2, 'new: Fetch second row (nested object)');

+is($row2[0]->attr->{NUM}, '92', 'Check obj.num');

+is_deeply($row2[0]->attr->{OBJ}->attr, {NUM=>'0', NAME=>undef}, 'Check 
obj.obj');

+

+...@row3 = $sth->fetchrow();

+ok (scalar @row3, 'new: Fetch third row (nested object)');

+is_deeply($row3[0]->attr, {NUM=>'93', OBJ=>undef}, 'Check obj');

+

+ok (!$sth->fetchrow(), 'new: No more rows expected (nested object)');

+

+#print STDERR Dumper(\...@row1, \...@row2, \...@row3);

+

+

 #cleanup 

 &drop_test_objects;

 $dbh->disconnect;

Reply via email to