2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / Mono.Data.Tds / Mono.Data.Tds.Protocol / Tds42.cs
index a335decb99349b9eea5b6ceb880b22d694a50f55..7051dd5fb5f90b17467e8fe11858baee7e6e7cad 100644 (file)
@@ -1,5 +1,5 @@
 //
-// Mono.Data.TdsClient.Internal.Tds42.cs
+// Mono.Data.Tds.Protocol.Tds42.cs
 //
 // Author:
 //   Tim Coleman (tim@timcoleman.com)
@@ -7,10 +7,31 @@
 // Copyright (C) 2002 Tim Coleman
 //
 
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System;
 
-namespace Mono.Data.TdsClient.Internal {
-        internal class Tds42 : Tds, ITds
+namespace Mono.Data.Tds.Protocol {
+        public class Tds42 : Tds
        {
                #region Fields
 
@@ -21,12 +42,12 @@ namespace Mono.Data.TdsClient.Internal {
                #region Constructors
 
                public Tds42 (string server, int port)
-                       : this (server, port, 512)
+                       : this (server, port, 512, 15)
                {
                }
 
-               public Tds42 (string server, int port, int packetSize)
-                       : base (server, port, packetSize, Version)
+               public Tds42 (string server, int port, int packetSize, int timeout)
+                       : base (server, port, packetSize, timeout, Version)
                {
                }
 
@@ -44,7 +65,6 @@ namespace Mono.Data.TdsClient.Internal {
 
                        byte pad = (byte) 0;
                        byte[] empty = new byte[0];
-                       bool isOkay = true;
 
                        Comm.StartPacket (TdsPacketType.Logon);
 
@@ -192,21 +212,78 @@ namespace Mono.Data.TdsClient.Internal {
 
                        Comm.SendPacket ();
 
-                       TdsPacketResult result;
+                       MoreResults = true;
+                       SkipToEnd ();
+
+                       return IsConnected;
+               }
 
-                       while (!((result = ProcessSubPacket()) is TdsPacketEndTokenResult)) {
-                               if (result is TdsPacketErrorResult) {
-                                       isOkay = false;
-                                       break;
+               protected override TdsDataColumnCollection ProcessColumnInfo ()
+               {
+                       byte precision;
+                       byte scale;
+                       int totalLength = Comm.GetTdsShort ();
+                       int bytesRead = 0;
+
+                       TdsDataColumnCollection result = new TdsDataColumnCollection ();
+
+                       while (bytesRead < totalLength) {
+                               scale = 0;
+                               precision = 0;
+
+                               int bufLength = -1;
+                               byte[] flagData = new byte[4];
+                               for (int i = 0; i < 4; i += 1) {
+                                       flagData[i] = Comm.GetByte ();
+                                       bytesRead += 1;
                                }
-                               // XXX Should really process some more types of packets.
-                       }
+                               bool nullable = (flagData[2] & 0x01) > 0;
+                               bool caseSensitive = (flagData[2] & 0x02) > 0;
+                               bool writable = (flagData[2] & 0x0c) > 0;
+                               bool autoIncrement = (flagData[2] & 0x10) > 0;
+
+                               string tableName = String.Empty;
+                               TdsColumnType columnType = (TdsColumnType) Comm.GetByte ();
 
-                       // XXX Possible bug.  What happend if this is cancelled before the logon
-                       // takes place?  Should isOkay be false?
+                               bytesRead += 1;
+
+                               if (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image) {
+                                       Comm.Skip (4);
+                                       bytesRead += 4;
+
+                                       int tableNameLength = Comm.GetTdsShort ();
+                                       bytesRead += 2;
+                                       tableName = Comm.GetString (tableNameLength);
+                                       bytesRead += tableNameLength;
+                                       bufLength = 2 << 31 - 1;
+                               }
+                               else if (columnType == TdsColumnType.Decimal || columnType == TdsColumnType.Numeric) {
+                                       bufLength = Comm.GetByte ();
+                                       bytesRead += 1;
+                                       precision = Comm.GetByte ();
+                                       bytesRead += 1;
+                                       scale = Comm.GetByte ();
+                                       bytesRead += 1;
+                               }
+                               else if (IsFixedSizeColumn (columnType))
+                                       bufLength = LookupBufferSize (columnType);
+                               else {
+                                       bufLength = (int) Comm.GetByte () & 0xff;
+                                       bytesRead += 1;
+                               }
+
+                               int index = result.Add (new TdsDataColumn ());
+                               result[index]["NumericPrecision"] = precision;
+                               result[index]["NumericScale"] = scale;
+                               result[index]["ColumnSize"] = bufLength;
+                               result[index]["ColumnName"] = ColumnNames[index];
+                               result[index]["ColumnType"] = columnType;
+                               result[index]["BaseTableName"] = tableName;
+                               result[index]["AllowDBNull"] = nullable;
+                               result[index]["IsReadOnly"] = !writable;
+                       }
 
-                       IsConnected = isOkay;
-                       return isOkay;
+                       return result;
                }
 
                #endregion // Methods