Merge pull request #2394 from Mailaender/patch-1
[mono.git] / mcs / class / Mono.Data.Tds / Mono.Data.Tds.Protocol / Tds80.cs
index 4349571eba41585f2c3e8f52ff7841886326d54a..cc5d2390ae59d43d91cb66800fccb16bfe9f7c55 100644 (file)
@@ -3,8 +3,10 @@
 //
 // Author:
 //   Tim Coleman (tim@timcoleman.com)
+//      Veerapuram Varadhan  (vvaradhan@novell.com)
 //
 // Copyright (C) 2002 Tim Coleman
+// Copyright (C) 2008,2009 Novell Inc.
 //
 
 //
@@ -32,7 +34,7 @@ using Mono.Data.Tds;
 using System;
 
 namespace Mono.Data.Tds.Protocol {
-        public class Tds80 : Tds
+       public class Tds80 : Tds70
        {
                #region Fields
 
@@ -42,28 +44,208 @@ namespace Mono.Data.Tds.Protocol {
 
                #region Constructors
 
+               [Obsolete ("Use the constructor that receives a lifetime parameter")]
                public Tds80 (string server, int port)
-                       : this (server, port, 512, 15)
+                       : this (server, port, 512, 15, 0)
                {
                }
 
+               [Obsolete ("Use the constructor that receives a lifetime parameter")]
                public Tds80 (string server, int port, int packetSize, int timeout)
-                       : base (server, port, packetSize, timeout, Version)
+                       : base (server, port, packetSize, timeout, 0, Version)
+               {
+               }
+
+               public Tds80 (string server, int port, int lifetime)
+                       : this (server, port, 512, 15, lifetime)
+               {
+               }
+
+               public Tds80 (string server, int port, int packetSize, int timeout, int lifeTime)
+                       : base (server, port, packetSize, timeout, lifeTime, Version)
                {
                }
 
                #endregion // Constructors
 
+               #region Properties
+               
+               protected override byte[] ClientVersion {
+                       get { return new byte[] {0x00, 0x0, 0x0, 0x71};}
+               }
+               protected override byte Precision {
+                       get { return 38; }
+               }
+               
+               #endregion // Properties
+               
                #region Methods
 
                public override bool Connect (TdsConnectionParameters connectionParameters)
                {
-                       throw new NotImplementedException ();
+                       //Console.WriteLine ("Tds80::Connect");
+                       return base.Connect (connectionParameters);
                }
 
-               protected override TdsDataColumnCollection ProcessColumnInfo ()
+               protected override void ProcessColumnInfo ()
+               {
+                       // We are connected to a Sql 7.0 server
+                       if (TdsVersion < TdsVersion.tds80) {
+                               base.ProcessColumnInfo ();
+                               return;
+                       }
+                       
+                       // VARADHAN: TDS 8 Debugging
+                       //Console.WriteLine ("Tds80.cs: In ProcessColumnInfo... entry");
+                       int numColumns = Comm.GetTdsShort ();
+                       //Console.WriteLine ("Column count={0}", numColumns); TDS 8 Debugging
+                       for (int i = 0; i < numColumns; i += 1) {
+                               byte[] flagData = new byte[4];
+                               for (int j = 0; j < 4; j += 1) 
+                                       flagData[j] = Comm.GetByte ();
+
+                               bool nullable = (flagData[2] & 0x01) > 0;
+                               //bool caseSensitive = (flagData[2] & 0x02) > 0;
+                               bool writable = (flagData[2] & 0x0c) > 0;
+                               bool autoIncrement = (flagData[2] & 0x10) > 0;
+                               bool isIdentity = (flagData[2] & 0x10) > 0;
+
+                               TdsColumnType columnType = (TdsColumnType) (Comm.GetByte () & 0xff);
+                               //Console.WriteLine ("Actual ColumnType: {0}", columnType);  TDS 8 Debugging
+
+                               if ((byte) columnType == 0xef)
+                                       columnType = TdsColumnType.NChar;
+
+                               TdsColumnType xColumnType = columnType;
+                               if (IsLargeType (columnType)) {
+                                       if (columnType != TdsColumnType.NChar)
+                                               columnType -= 128;
+                               }
+
+                               int columnSize;
+                               string tableName = null;
+                               byte[] collation = null;
+                               int lcid = 0, sortId = 0;
+
+                               if (IsBlobType (columnType)) {
+                                       columnSize = Comm.GetTdsInt ();
+                               } else if (IsFixedSizeColumn (columnType)) {
+                                       columnSize = LookupBufferSize (columnType);
+                               } else if (IsLargeType (xColumnType)) {
+                                       columnSize = Comm.GetTdsShort ();
+                               } else  {
+                                       columnSize = Comm.GetByte () & 0xff;
+                               }
+
+                               if (xColumnType == TdsColumnType.BigChar || xColumnType == TdsColumnType.BigNVarChar ||
+                                   xColumnType == TdsColumnType.BigVarChar || xColumnType == TdsColumnType.NChar ||
+                                   xColumnType == TdsColumnType.NVarChar ||   xColumnType == TdsColumnType.Text ||
+                                   xColumnType == TdsColumnType.NText) {
+                                   // Read collation for SqlServer 2000 and beyond
+                                   collation = Comm.GetBytes (5, true);
+                                       lcid = TdsCollation.LCID (collation);
+                                       sortId = TdsCollation.SortId (collation);
+                               }
+
+                               if (IsBlobType (columnType)) {
+                                       tableName = Comm.GetString (Comm.GetTdsShort ());
+                                       //Console.WriteLine ("Tablename: "+tableName);  TDS 8 Debugging
+                               }
+
+                               byte precision = 0;
+                               byte scale = 0;
+
+                               switch (columnType) {
+                               case TdsColumnType.NText:
+                               case TdsColumnType.NChar:
+                               case TdsColumnType.NVarChar:
+                                       columnSize /= 2;
+                                       break;
+                               case TdsColumnType.Decimal:
+                               case TdsColumnType.Numeric:
+                                       //Comm.Skip (1);
+                                       precision = Comm.GetByte ();
+                                       //Console.WriteLine ("Precision: {0}", precision);  TDS 8 Debugging
+                                       scale = Comm.GetByte ();
+                                       //Console.WriteLine ("Scale: {0}", scale);  TDS 8 Debugging
+                                       break;
+                               }
+
+                               string columnName = Comm.GetString (Comm.GetByte ());
+
+                               TdsDataColumn col = new TdsDataColumn ();
+                               Columns.Add (col);
+                               col.ColumnType = columnType;
+                               col.ColumnName = columnName;
+                               col.IsAutoIncrement = autoIncrement;
+                               col.IsIdentity = isIdentity;
+                               col.ColumnSize = columnSize;
+                               col.NumericPrecision = precision;
+                               col.NumericScale = scale;
+                               col.IsReadOnly = !writable;
+                               col.AllowDBNull = nullable;
+                               col.BaseTableName = tableName;
+                               col.LCID = lcid;
+                               col.SortOrder = sortId;
+                       }
+                       //Console.WriteLine ("Tds80.cs: In ProcessColumnInfo... exit");  TDS 8 Debugging
+               }
+
+               protected override void ProcessOutputParam ()
+               {
+                       // We are connected to a Sql 7.0 server
+                       if (TdsVersion < TdsVersion.tds80) {
+                               base.ProcessOutputParam ();
+                               return;
+                       }
+
+                       GetSubPacketLength ();
+                       
+                       Comm.Skip ((Comm.GetByte () & 0xff) <<1); // Parameter name
+                       Comm.Skip (1);  // Status: 0x01 - in case of OUTPUT parameter
+                                                       // Status: 0x02 - in case of return value of UDF
+                       Comm.Skip (4);  // Usertype - sizeof (ULong)
+
+                       TdsColumnType colType = (TdsColumnType) Comm.GetByte ();
+                       object value = GetColumnValue (colType, true);
+                       OutputParameters.Add (value);
+               }
+               
+               public override void Execute (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
+               {
+                       // We are connected to a Sql 7.0 server
+                       if (TdsVersion < TdsVersion.tds80) {
+                               base.Execute (commandText, parameters, timeout, wantResults);
+                               return;
+                       }
+
+                       Parameters = parameters;
+                       string sql = commandText;
+
+                       if (Parameters != null && Parameters.Count > 0) {
+                               ExecRPC (TdsRpcProcId.ExecuteSql, commandText, parameters, timeout, wantResults);
+                       } else {
+                               if (wantResults)
+                                       sql = BuildExec (commandText);
+                               ExecuteQuery (sql, timeout, wantResults);
+                       }
+               }
+               
+               public override void ExecPrepared (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
                {
-                       throw new NotImplementedException ();
+                       Parameters = parameters;
+                       // We are connected to a Sql 7.0 server
+                       if (TdsVersion < TdsVersion.tds80 || 
+                           Parameters == null || Parameters.Count < 1) {
+                               base.ExecPrepared (commandText, parameters, timeout, wantResults);
+                               return;
+                       }
+                       TdsMetaParameterCollection parms = new TdsMetaParameterCollection ();
+                       parms.Add (new TdsMetaParameter ("@Handle", "int", Int32.Parse (commandText)));
+                       foreach (TdsMetaParameter parm in Parameters)
+                               parms.Add (parm);
+                       
+                       ExecRPC ("sp_execute", parms, timeout, wantResults);                    
                }
 
                #endregion // Methods