2010-06-15 Veerapuram Varadhan <vvaradhan@novell.com>
[mono.git] / mcs / class / Mono.Data.Tds / Mono.Data.Tds.Protocol / Tds80.cs
1 //
2 // Mono.Data.Tds.Protocol.Tds80.cs
3 //
4 // Author:
5 //   Tim Coleman (tim@timcoleman.com)
6 //       Veerapuram Varadhan  (vvaradhan@novell.com)
7 //
8 // Copyright (C) 2002 Tim Coleman
9 // Copyright (C) 2008,2009 Novell Inc.
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using Mono.Data.Tds;
34 using System;
35
36 namespace Mono.Data.Tds.Protocol {
37         public class Tds80 : Tds70
38         {
39                 #region Fields
40
41                 public static readonly TdsVersion Version = TdsVersion.tds80;
42
43                 #endregion // Fields
44
45                 #region Constructors
46
47                 public Tds80 (string server, int port)
48                         : this (server, port, 512, 15)
49                 {
50                 }
51
52                 public Tds80 (string server, int port, int packetSize, int timeout)
53                         : base (server, port, packetSize, timeout, Version)
54                 {
55                 }
56
57                 #endregion // Constructors
58
59                 #region Properties
60                 
61                 protected override byte[] ClientVersion {
62                         get { return new byte[] {0x00, 0x0, 0x0, 0x71};}
63                 }
64                 #endregion // Properties
65                 
66                 #region Methods
67
68                 public override bool Connect (TdsConnectionParameters connectionParameters)
69                 {
70                         //Console.WriteLine ("Tds80::Connect");
71                         return base.Connect (connectionParameters);
72                 }
73
74                 protected override void ProcessColumnInfo ()
75                 {
76                         // We are connected to a Sql 7.0 server
77                         if (TdsVersion < TdsVersion.tds80) {
78                                 base.ProcessColumnInfo ();
79                                 return;
80                         }
81                         
82                         // VARADHAN: TDS 8 Debugging
83                         //Console.WriteLine ("Tds80.cs: In ProcessColumnInfo... entry");
84                         int numColumns = Comm.GetTdsShort ();
85                         //Console.WriteLine ("Column count={0}", numColumns); TDS 8 Debugging
86                         for (int i = 0; i < numColumns; i += 1) {
87                                 byte[] flagData = new byte[4];
88                                 for (int j = 0; j < 4; j += 1) 
89                                         flagData[j] = Comm.GetByte ();
90
91                                 bool nullable = (flagData[2] & 0x01) > 0;
92                                 //bool caseSensitive = (flagData[2] & 0x02) > 0;
93                                 bool writable = (flagData[2] & 0x0c) > 0;
94                                 bool autoIncrement = (flagData[2] & 0x10) > 0;
95                                 bool isIdentity = (flagData[2] & 0x10) > 0;
96
97                                 TdsColumnType columnType = (TdsColumnType) (Comm.GetByte () & 0xff);
98                                 //Console.WriteLine ("Actual ColumnType: {0}", columnType);  TDS 8 Debugging
99
100                                 if ((byte) columnType == 0xef)
101                                         columnType = TdsColumnType.NChar;
102
103                                 TdsColumnType xColumnType = columnType;
104                                 if (IsLargeType (columnType)) {
105                                         if (columnType != TdsColumnType.NChar)
106                                                 columnType -= 128;
107                                 }
108
109                                 int columnSize;
110                                 string tableName = null;
111                                 byte[] collation = null;
112                                 int lcid = 0, sortId = 0;
113
114                                 if (IsBlobType (columnType)) {
115                                         columnSize = Comm.GetTdsInt ();
116                                 } else if (IsFixedSizeColumn (columnType)) {
117                                         columnSize = LookupBufferSize (columnType);
118                                 } else if (IsLargeType (xColumnType)) {
119                                         columnSize = Comm.GetTdsShort ();
120                                 } else  {
121                                         columnSize = Comm.GetByte () & 0xff;
122                                 }
123
124                                 if (xColumnType == TdsColumnType.BigChar || xColumnType == TdsColumnType.BigNVarChar ||
125                                     xColumnType == TdsColumnType.BigVarChar || xColumnType == TdsColumnType.NChar ||
126                                     xColumnType == TdsColumnType.NVarChar ||   xColumnType == TdsColumnType.Text ||
127                                     xColumnType == TdsColumnType.NText) {
128                                     // Read collation for SqlServer 2000 and beyond
129                                     collation = Comm.GetBytes (5, true);
130                                         lcid = TdsCollation.LCID (collation);
131                                         sortId = TdsCollation.SortId (collation);
132                                 }
133
134                                 if (IsBlobType (columnType)) {
135                                         tableName = Comm.GetString (Comm.GetTdsShort ());
136                                         //Console.WriteLine ("Tablename: "+tableName);  TDS 8 Debugging
137                                 }
138
139                                 byte precision = 0;
140                                 byte scale = 0;
141
142                                 switch (columnType) {
143                                 case TdsColumnType.NText:
144                                 case TdsColumnType.NChar:
145                                 case TdsColumnType.NVarChar:
146                                         columnSize /= 2;
147                                         break;
148                                 case TdsColumnType.Decimal:
149                                 case TdsColumnType.Numeric:
150                                         //Comm.Skip (1);
151                                         precision = Comm.GetByte ();
152                                         //Console.WriteLine ("Precision: {0}", precision);  TDS 8 Debugging
153                                         scale = Comm.GetByte ();
154                                         //Console.WriteLine ("Scale: {0}", scale);  TDS 8 Debugging
155                                         break;
156                                 }
157
158                                 string columnName = Comm.GetString (Comm.GetByte ());
159
160                                 TdsDataColumn col = new TdsDataColumn ();
161                                 Columns.Add (col);
162 #if NET_2_0
163                                 col.ColumnType = columnType;
164                                 col.ColumnName = columnName;
165                                 col.IsAutoIncrement = autoIncrement;
166                                 col.IsIdentity = isIdentity;
167                                 col.ColumnSize = columnSize;
168                                 col.NumericPrecision = precision;
169                                 col.NumericScale = scale;
170                                 col.IsReadOnly = !writable;
171                                 col.AllowDBNull = nullable;
172                                 col.BaseTableName = tableName;
173                                 col.LCID = lcid;
174                                 col.SortOrder = sortId;
175 #else
176                                 col ["ColumnType"] = columnType;
177                                 col ["ColumnName"] = columnName;
178                                 col ["IsAutoIncrement"] = autoIncrement;
179                                 col ["IsIdentity"] = isIdentity;
180                                 col ["ColumnSize"] = columnSize;
181                                 col ["NumericPrecision"] = precision;
182                                 col ["NumericScale"] = scale;
183                                 col ["IsReadOnly"] = !writable;
184                                 col ["AllowDBNull"] = nullable;
185                                 col ["BaseTableName"] = tableName;
186                                 col ["LCID"] = lcid;
187                                 col ["SortOrder"] = sortId;
188 #endif
189                         }
190                         //Console.WriteLine ("Tds80.cs: In ProcessColumnInfo... exit");  TDS 8 Debugging
191                 }
192
193                 protected override void ProcessOutputParam ()
194                 {
195                         // We are connected to a Sql 7.0 server
196                         if (TdsVersion < TdsVersion.tds80) {
197                                 base.ProcessOutputParam ();
198                                 return;
199                         }
200
201                         GetSubPacketLength ();
202                         
203                         Comm.Skip ((Comm.GetByte () & 0xff) <<1); // Parameter name
204                         Comm.Skip (1);  // Status: 0x01 - in case of OUTPUT parameter
205                                                         // Status: 0x02 - in case of return value of UDF
206                         Comm.Skip (4);  // Usertype - sizeof (ULong)
207
208                         TdsColumnType colType = (TdsColumnType) Comm.GetByte ();
209                         object value = GetColumnValue (colType, true);
210                         OutputParameters.Add (value);
211                 }
212                 
213                 public override void Execute (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
214                 {
215                         // We are connected to a Sql 7.0 server
216                         if (TdsVersion < TdsVersion.tds80) {
217                                 base.Execute (commandText, parameters, timeout, wantResults);
218                                 return;
219                         }
220
221                         Parameters = parameters;
222                         string sql = commandText;
223
224                         if (Parameters != null && Parameters.Count > 0) {
225                                 ExecRPC (TdsRpcProcId.ExecuteSql, commandText, parameters, timeout, wantResults);
226                         } else {
227                                 if (wantResults)
228                                         sql = BuildExec (commandText);
229                                 ExecuteQuery (sql, timeout, wantResults);
230                         }
231                 }
232
233                 #endregion // Methods
234         }
235 }