2008-09-24 Daniel Morgan <monodanmorg@yahoo.com>
authorDaniel Morgan <monodanmorg@yahoo.com>
Thu, 25 Sep 2008 01:46:57 +0000 (01:46 -0000)
committerDaniel Morgan <monodanmorg@yahoo.com>
Thu, 25 Sep 2008 01:46:57 +0000 (01:46 -0000)
* Test/testblob.cs
* Test/TestOracleClient.cs: update tests for parameter type of blob

* System.Data.OracleClient/OracleLob.cs: position was never
being reset to the offset causing the reading of a Blob to
be out of range

* System.Data.OracleClient/OracleParameter.cs: fixes for
character and blob types

svn path=/trunk/mcs/; revision=114050

mcs/class/System.Data.OracleClient/ChangeLog
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleLob.cs
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
mcs/class/System.Data.OracleClient/Test/TestOracleClient.cs
mcs/class/System.Data.OracleClient/Test/testblob.cs

index 94095213c94ab40604d7bc0ef0336f71d5b36c2d..531a9e93f5a8d8ec525d1c21bc2764aa70b707e3 100644 (file)
@@ -1,3 +1,15 @@
+2008-09-24  Daniel Morgan <monodanmorg@yahoo.com>
+
+       * Test/testblob.cs
+       * Test/TestOracleClient.cs: update tests for parameter type of blob
+
+       * System.Data.OracleClient/OracleLob.cs: position was never
+       being reset to the offset causing the reading of a Blob to
+       be out of range
+
+       * System.Data.OracleClient/OracleParameter.cs: fixes for 
+       character and blob types
+
 2008-09-16  Daniel Morgan <monodanmorg@yahoo.com>
 
        * System.Data.OracleClient/OracleBFile.cs: do not
index 59e7a0147c303e8239eefb88eec8a12ff96b1d38..1454769807a56719428d64d0b3cadb22ad493057 100644 (file)
@@ -331,6 +331,7 @@ namespace System.Data.OracleClient
                        int bytesRead;
                        byte[] output = new byte [count];
 
+                       position = offset;
                        bytesRead = locator.Read (output, (uint) Position + 1, (uint) count, LobType == OracleType.Blob);
                        output.CopyTo (buffer, offset);
                        position += bytesRead;
@@ -394,7 +395,6 @@ namespace System.Data.OracleClient
                                value = new byte[count];
                                Array.Copy (buffer, offset, value, 0, count);
                        }
-
                        position += locator.Write (value, (uint) Position + 1, (uint) value.Length, LobType);
                }
 
index 627cd354fd0e099886bca780a838a673d5e5bf75..82bef0e698ffb29fca6c2f987b13f9b6e15f4d5d 100644 (file)
@@ -433,14 +433,23 @@ namespace System.Data.OracleClient
                                        if (direction == ParameterDirection.Input || 
                                                direction == ParameterDirection.InputOutput) {
 
-                                               svalue = v.ToString () + '\0';
+                                               svalue = v.ToString ();
+
+                                               if (direction == ParameterDirection.Input && size > 0 && svalue.Length > size)
+                                                       svalue = svalue.Substring(0, size);
+
+                                               svalue = svalue.ToString () + '\0';
                                        }
 
                                        // set bind length to size of data
-                                       bindSize = (size + 1) * 4;
+                                       //bindSize = (size + 1) * 4;
+                                       if (direction == ParameterDirection.Input)
+                                               bindSize = Encoding.UTF8.GetMaxByteCount (svalue.Length);
+                                       else
+                                               bindSize = Encoding.UTF8.GetMaxByteCount (size + 1);
 
                                        // allocate memory based on bind length
-                                       bytes = new byte[bindSize];                             
+                                       bytes = new byte [bindSize];                            
 
                                        if (direction == ParameterDirection.Input ||
                                                direction == ParameterDirection.InputOutput) {
@@ -646,9 +655,26 @@ namespace System.Data.OracleClient
                                        break;
                                case OciDataType.Blob:
                                        if (direction == ParameterDirection.Input) {
-                                               bytes = (byte[]) v;
-                                               bindType = OciDataType.LongRaw;
-                                               bindSize = bytes.Length;
+                                               if (v is byte[]) {
+                                                       bytes = (byte[]) v;
+                                                       bindType = OciDataType.LongRaw;
+                                                       bindSize = bytes.Length;
+                                               }
+                                               else if (v is OracleLob) {
+                                                       OracleLob lob = (OracleLob) v;
+                                                       if (lob.LobType == OracleType.Blob) {
+                                                               lobLocator = lob.Locator;
+                                                               bindOutValue = lobLocator.Handle;
+                                                               bindValue = lobLocator.Handle;
+                                                               lobLocator.ErrorHandle = connection.ErrorHandle;
+                                                               lobLocator.Service = connection.ServiceContext;
+                                                               useRef = true;
+                                                       }
+                                                       else
+                                                               throw new NotImplementedException("For OracleType.Blob, data type OracleLob of LobType Clob/NClob is not implemented.");
+                                               }
+                                               else
+                                                       throw new NotImplementedException ("For OracleType.Blob, data type not implemented: " + v.GetType().ToString()); // ?
                                        }
                                        else if (direction == ParameterDirection.InputOutput) {
                                                // not the exact error that .net 2.0 throws, but this is better
@@ -656,15 +682,26 @@ namespace System.Data.OracleClient
                                        }
                                        else {
                                                bindSize = -1;
-                                               lobLocator = (OciLobLocator) connection.Environment.Allocate (OciHandleType.LobLocator);
+                                               if (value != null && value is OracleLob) {
+                                                       OracleLob blob = (OracleLob) value;
+                                                       if (blob.LobType == OracleType.Blob)
+                                                               if (value != OracleLob.Null) {
+                                                                       lobLocator = blob.Locator;
+                                                                       byte[] bs = (byte[]) blob.Value;
+                                                                       bindSize = bs.Length;
+                                                               }
+                                               }
                                                if (lobLocator == null) {
-                                                       OciErrorInfo info = connection.ErrorHandle.HandleError ();
-                                                       throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                                                       lobLocator = (OciLobLocator) connection.Environment.Allocate (OciHandleType.LobLocator);
+                                                       if (lobLocator == null) {
+                                                               OciErrorInfo info = connection.ErrorHandle.HandleError ();
+                                                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                                                       }
                                                }
                                                bindOutValue = lobLocator.Handle;
                                                bindValue = lobLocator.Handle;
                                                lobLocator.ErrorHandle = connection.ErrorHandle;
-                                               lobLocator.Service = statement.Service;
+                                               lobLocator.Service = connection.ServiceContext;
                                                useRef = true;
                                        }
                                        break;
@@ -722,7 +759,7 @@ namespace System.Data.OracleClient
                                                        OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
 
                                                        bindType = OciDataType.String;
-                                                       bindSize = svalue.Length;
+                                                       bindSize = bytes.Length;
                                                } // else oracleType
                                        } // else - Input, Ouput...
                                        break;
@@ -1090,7 +1127,7 @@ namespace System.Data.OracleClient
                                throw new ArgumentException (exception);
                        }
 
-                       if (!inferring)
+                       if (!oracleTypeSet || !inferring )
                                oracleType = type;
                        bindOracleType = type;
                }
@@ -1182,9 +1219,15 @@ namespace System.Data.OracleClient
                                break;
                        case OciDataType.Blob:
                        case OciDataType.Clob:
-                               OracleLob lob = new OracleLob (lobLocator, ociType);
-                               lob.connection = connection;
-                               value = lob;
+                               if (value != null && value is OracleLob && value != OracleLob.Null) {
+                                       OracleLob lob2 = (OracleLob) value;
+                                       lob2.connection = connection;
+                               }
+                               else {
+                                       OracleLob lob = new OracleLob (lobLocator, ociType);
+                                       lob.connection = connection;
+                                       value = lob;
+                               }
                                break;
                        case OciDataType.RSet: // REF CURSOR                            
                                OciStatementHandle cursorStatement = GetOutRefCursor (cmd);
index 9843419b797156ea411b0223783ee54dad65f36e..da95b69cedbe0ec5e9b584af7b8f129a0758eead 100644 (file)
@@ -2941,6 +2941,247 @@ namespace Test.OracleClient
                        p4.OracleType = OracleType.Clob;
                        Console.WriteLine("p4.OracleType [Clob]: " + p4.OracleType.ToString());
                        Console.WriteLine();
+
+                       OracleParameter p5 = new OracleParameter ((string) null, new DateTime (2005, 3, 8));
+                       Console.WriteLine("p5.OracleType [DateTime]: " + p5.OracleType.ToString());
+               }
+
+                public static void InsertBlobTest(OracleConnection con)
+                {
+                       checkTNS();
+                       SetupMyPackage(con);
+                        InsertBlob(con);
+                }
+
+               public static void checkTNS()
+               {
+                       //string tnsAdmin = System.Environment.GetEnvironmentVariable("TNS_ADMIN");
+                       //if ( (tnsAdmin == null)|| (string.Empty.Equals(tnsAdmin)) )
+                       //{
+                       //      System.Environment.SetEnvironmentVariable("TNS_ADMIN", "~/instantclient");
+                       //}
+               }
+
+               public static decimal InsertBlob(OracleConnection con)
+               {
+                       byte[] ByteArray = new byte[2000]; // test Blob data
+                       byte j = 0;
+                       for (int i = 0; i < ByteArray.Length; i++) {
+                               ByteArray[i] = j;
+                               if (j > 255)
+                                       j = 0;
+                               j++;
+                       }
+                       Console.WriteLine("Test Blob Data beginning: " + GetHexString (ByteArray));
+
+                       decimal retVal = -1;
+
+                       string sproc = "MyPackage" + ".InsertBlob";
+
+                       OracleCommand cmd = new OracleCommand();
+                       cmd.CommandText = sproc;
+                       cmd.CommandType = CommandType.StoredProcedure;
+                       cmd.Connection = con;
+                       //cmd.Connection.Open();
+                       cmd.Transaction = cmd.Connection.BeginTransaction();
+
+                       try {
+                               OracleParameter p1 = new OracleParameter("i_Sig_File", OracleType.Blob);
+                               p1.Direction = ParameterDirection.Input;
+
+                               //EXCEPTION thrown here
+                               //p1.Value = GetOracleLob(cmd.Transaction, ByteArray);
+                               OracleLob lob2 = GetOracleLob(cmd.Transaction, ByteArray);
+                               byte[] b2 = (byte[]) lob2.Value;
+                               Console.WriteLine("Test Blob Data here: " + GetHexString (b2));
+                               p1.Value = lob2.Value;
+                               //p1.Value = ByteArray;
+
+                               cmd.Parameters.Add(p1);
+
+                               cmd.ExecuteNonQuery();
+
+                               cmd.Transaction.Commit();
+                       
+                               OracleCommand select = con.CreateCommand ();
+                               //select.Transaction = transaction;
+                               select.CommandText = "SELECT BLOB_COLUMN FROM BLOBTEST2";
+                               Console.WriteLine ("  SELECTING A BLOB (Binary) VALUE FROM BLOBTEST2");
+
+                               OracleDataReader reader = select.ExecuteReader ();
+                               if (!reader.Read ())
+                                       Console.WriteLine ("ERROR: RECORD NOT FOUND");
+
+                               Console.WriteLine ("  TESTING OracleLob OBJECT ...");
+                               if (reader.IsDBNull(0))
+                                       Console.WriteLine("Lob IsNull");
+                               else {
+                                       OracleLob lob = reader.GetOracleLob (0);
+                                       if (lob == OracleLob.Null)
+                                               Console.WriteLine("Lob is OracleLob.Null");
+                                       else {
+                                               byte[] blob = (byte[]) lob.Value;
+                                               string result = GetHexString(blob);
+                                               Console.WriteLine("Blob result: " + result);
+                                               if (ByteArrayCompare (ByteArray, blob))
+                                                       Console.WriteLine("ByteArray and blob are the same: good");
+                                               else
+                                                       Console.WriteLine("ByteArray and blob are not the same: bad");
+                                       }
+                               }
+                   }
+                   catch(Exception ex) {
+                       Console.WriteLine("I exploded:" + ex.ToString());
+                       cmd.Transaction.Rollback();
+
+                   }
+
+                   return retVal;
+
+               }
+
+               private static OracleLob GetOracleLob(OracleTransaction transaction, byte[] blob)
+               {
+                   string BLOB_CREATE = "DECLARE dpBlob BLOB; "        
+                   + "BEGIN "
+                   + "   DBMS_LOB.CREATETEMPORARY(dpBlob , False, 0); " 
+                   + "  :tempBlob := dpBlob; "
+                   + "END;";
+
+                   OracleLob tempLob = OracleLob.Null;
+                   if (blob != null)
+                   {
+                       // Create a new command using the same connection
+                       OracleCommand command = transaction.Connection.CreateCommand();
+
+                       // Assign the transaction to the command
+                       command.Transaction = transaction;
+
+                       // Create blob storage on the Oracle server
+                       command.CommandText = BLOB_CREATE;
+
+                       // Add a new output paramter to accept the blob storage reference
+                       OracleParameter parm = new OracleParameter("tempBlob", OracleType.Blob);
+                       parm.Direction = ParameterDirection.Output;
+                       command.Parameters.Add(parm);
+//                     command.Parameters.Add( 
+//                             new OracleParameter("tempBlob", OracleType.Blob)).Direction =
+//                                     ParameterDirection.Output;
+
+                       // Fire as your guns bear...
+                       command.ExecuteNonQuery();
+
+                       // Retrieve the blob stream from the OracleLob parameter 
+                       //tempLob = (OracleLob)command.Parameters[0].Value;
+                       tempLob = (OracleLob) parm.Value;
+
+                       // Prevent server side events from firing while we write to the stream
+                       tempLob.BeginBatch(OracleLobOpenMode.ReadWrite);
+
+                       // Write bytes to the stream
+                       tempLob.Write(blob, 0, blob.Length);
+                       
+                       // Resume firing server events
+                       tempLob.EndBatch();
+                   }
+
+                   return tempLob;
+               }
+
+               static void SetupMyPackage(OracleConnection con) \r
+               {\r
+                       Console.WriteLine("Setup Oracle package curspkg_join...");\r
+               \r
+                       Console.WriteLine ("  Drop table BLOBTEST2 ...");
+                       try {
+                               OracleCommand cmd2 = con.CreateCommand ();
+                               //cmd2.Transaction = transaction;
+                               cmd2.CommandText = "DROP TABLE BLOBTEST2";
+                               cmd2.ExecuteNonQuery ();
+                       }
+                       catch (OracleException) {
+                               // ignore if table already exists
+                       }
+
+                       Console.WriteLine ("  CREATE TABLE ...");
+
+                       OracleCommand create = con.CreateCommand ();
+                       //create.Transaction = transaction;
+                       create.CommandText = "CREATE TABLE BLOBTEST2 (BLOB_COLUMN BLOB)";
+                       create.ExecuteNonQuery ();
+
+                       create.CommandText = "commit";\r
+                       create.ExecuteNonQuery();\r
+
+                       Console.Error.WriteLine("    create or replace package MyPackage...");
+                       OracleCommand cmd = con.CreateCommand();\r
+                       cmd.CommandText = \r
+                               "CREATE OR REPLACE PACKAGE MyPackage AS\n" +\r
+                               " Procedure InsertBlob (i_Sig_File blob);\n" +\r
+                               "END MyPackage;";\r
+                       cmd.ExecuteNonQuery();
+\r
+                       Console.Error.WriteLine("    create or replace package body MyPackage...");                     
+                       cmd.CommandText = \r
+                               "CREATE OR REPLACE PACKAGE BODY MyPackage AS\n" +\r
+                               "   Procedure InsertBlob (i_Sig_File blob)\n" +\r
+                               "   IS\n" +\r
+                               "   BEGIN\n" +
+                               "       INSERT INTO BLOBTEST2 (BLOB_COLUMN) VALUES(i_Sig_File); " +
+                               "   END InsertBlob; " +\r
+                               "END MyPackage;";\r
+                       cmd.ExecuteNonQuery();
+
+                       cmd.CommandText = "commit";\r
+                       cmd.ExecuteNonQuery();\r
+               }\r
+
+               static byte[] ByteArrayCombine (byte[] b1, byte[] b2) 
+               {
+                       if (b1 == null)
+                               b1 = new byte[0];
+                       if (b2 == null)
+                               b2 = new byte[0];
+               
+                       byte[] bytes = new byte[b1.Length + b2.Length];
+                       int i = 0;
+                       for (int j = 0; j < b1.Length; j++) {
+                               bytes[i] = b1[j];
+                               i++;
+                       }
+                       for (int k = 0; k < b2.Length; k++) {
+                               bytes[i] = b2[k];
+                               i++;
+                       }
+                       return bytes;
+               }
+
+               static bool ByteArrayCompare(byte[] ba1, byte[] ba2)
+               {
+                   if (ba1 == null && ba2 == null)
+                       return true;
+
+                   if (ba1 == null)
+                       return false;
+
+                   if (ba2 == null)
+                       return false;
+
+                   if (ba1.Length != ba2.Length)
+                       return false;
+
+                  // for (int i = 0; i < ba1.Length; i++)
+                  // {
+                       //Console.WriteLine("i: " + i.ToString() + " ba1: " + ba1[i].ToString() + " ba2: " + ba2[i].ToString());
+                   //}
+
+                   for (int i = 0; i < ba1.Length; i++)
+                   {
+                       if (ba1[i] != ba2[i])
+                           return false;
+                   }
+
+                   return true;
                }
 
                [STAThread]
@@ -2974,6 +3215,8 @@ namespace Test.OracleClient
 
                        ShowConnectionProperties (con1);
 
+                       InsertBlobTest (con1);
+
                        Console.WriteLine ("Mono Oracle Test BEGIN ...");
                        MonoTest (con1);
                        Console.WriteLine ("Mono Oracle Test END ...");
index e463f1cfaa84a84a98fc613a0d9d2bba5a8d109d..ffa5022cf53e9a7b37f02a6f92fee0936cdb4607 100644 (file)
@@ -10,6 +10,7 @@ class TestBlob
        static string infilename = @"../../../tools/mono-win32-setup-dark.bmp";
        static string outfilename = @"mono-win32-setup-dark2.bmp";
        static string connectionString = "Data Source=testdb;User ID=scott;Password=tiger";
+       static byte[] bytes1 = null;
 
        public static void Main (string[] args) 
        {
@@ -44,6 +45,11 @@ class TestBlob
                Console.WriteLine ("  CHUNK SIZE: {0}", lob2.ChunkSize);
 
                byte[] lobvalue = (byte[]) lob2.Value;
+               
+               if (ByteArrayCompare(bytes1, lobvalue) == true)
+                       Console.WriteLine("bytes1 and bytes2 are equal: good");
+               else 
+                       Console.WriteLine("bytes1 and bytes2 are not equal: bad");
 
                FileStream fs = new FileStream(outfilename, FileMode.CreateNew);
                BinaryWriter w = new BinaryWriter(fs);
@@ -68,7 +74,7 @@ class TestBlob
                        cmd2.CommandText = "DROP TABLE BLOBTEST";
                        cmd2.ExecuteNonQuery ();
                }
-               catch (OracleException oe1) {
+               catch (OracleException) {
                        // ignore if table already exists
                }
 
@@ -100,7 +106,7 @@ class TestBlob
                Console.WriteLine ("  LENGTH: {0}", lob.Length);
                Console.WriteLine ("  CHUNK SIZE: {0}", lob.ChunkSize);
 
-               try {
+               //try {
                        if (File.Exists(infilename) == false) {
                                Console.WriteLine("Filename does not exist: " + infilename);
                                return;
@@ -116,6 +122,7 @@ class TestBlob
                        while(bytes.Length > 0) {
                                Console.WriteLine("byte count: " + bytes.Length.ToString());
                                lob.Write (bytes, 0, bytes.Length);
+                               bytes1 = ByteArrayCombine (bytes1, bytes);
                                if (bytes.Length < bufferLen)
                                        break;
                                bytes = r.ReadBytes (bufferLen);
@@ -123,11 +130,11 @@ class TestBlob
 
                        r.Close();
                        fs.Close ();    
-               }
-               catch (Exception e) {
-                       Console.WriteLine("The file could not be read:");
-                       Console.WriteLine(e.Message);
-               }
+               //}
+               //catch (Exception e) {
+               //      Console.WriteLine("The file could not be read:");
+               //      Console.WriteLine(e.Message);
+               //}
 
                lob.Close ();
 
@@ -143,4 +150,53 @@ class TestBlob
                insert = null;
                select = null;
        }
+
+       static byte[] ByteArrayCombine (byte[] b1, byte[] b2) 
+       {
+               if (b1 == null)
+                       b1 = new byte[0];
+               if (b2 == null)
+                       b2 = new byte[0];
+               
+               byte[] bytes = new byte[b1.Length + b2.Length];
+               int i = 0;
+               for (int j = 0; j < b1.Length; j++) {
+                       bytes[i] = b1[j];
+                       i++;
+               }
+               for (int k = 0; k < b2.Length; k++) {
+                       bytes[i] = b2[k];
+                       i++;
+               }
+               return bytes;
+       }
+
+        static bool ByteArrayCompare(byte[] ba1, byte[] ba2)
+        {
+            if (ba1 == null && ba2 == null)
+                return true;
+
+            if (ba1 == null)
+                return false;
+
+            if (ba2 == null)
+                return false;
+
+            if (ba1.Length != ba2.Length)
+                return false;
+
+            for (int i = 0; i < ba1.Length; i++)
+            {
+               Console.WriteLine("i: " + i.ToString() + " ba1: " + ba1[i].ToString() + " ba2: " + ba2[i].ToString());
+            }
+
+            for (int i = 0; i < ba1.Length; i++)
+            {
+                if (ba1[i] != ba2[i])
+                    return false;
+            }
+
+            return true;
+        }
+
 }