2 // Mono.Data.TdsClient.Internal.Tds42.cs
5 // Tim Coleman (tim@timcoleman.com)
7 // Copyright (C) 2002 Tim Coleman
12 namespace Mono.Data.TdsClient.Internal {
13 internal class Tds42 : Tds
17 public static readonly TdsVersion Version = TdsVersion.tds42;
23 public Tds42 (string server, int port)
24 : this (server, port, 512, 15)
28 public Tds42 (string server, int port, int packetSize, int timeout)
29 : base (server, port, packetSize, timeout, Version)
33 #endregion // Constructors
37 public override bool Connect (TdsConnectionParameters connectionParameters)
40 throw new InvalidOperationException ("The connection is already open.");
42 SetCharset (connectionParameters.Charset);
43 SetLanguage (connectionParameters.Language);
46 byte[] empty = new byte[0];
48 Comm.StartPacket (TdsPacketType.Logon);
50 // hostname (offset 0)
51 byte[] tmp = Comm.Append (connectionParameters.Hostname, 30, pad);
52 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
54 // username (offset 31 0x1f)
55 tmp = Comm.Append (connectionParameters.User, 30, pad);
56 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
58 // password (offset 62 0x3e)
59 tmp = Comm.Append (connectionParameters.Password, 30, pad);
60 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
62 // hostproc (offset 93 0x5d)
63 Comm.Append ("00000116", 8, pad);
65 // unused (offset 109 0x6d)
66 Comm.Append (empty, (30-14), pad);
69 Comm.Append ((byte) 0x0);
70 Comm.Append ((byte) 0xa0);
71 Comm.Append ((byte) 0x24);
72 Comm.Append ((byte) 0xcc);
73 Comm.Append ((byte) 0x50);
74 Comm.Append ((byte) 0x12);
77 Comm.Append ((byte) 8);
79 // Byte order of 2 byte ints
80 // 2 = <MSB, LSB>, 3 = <LSB, MSB>
81 Comm.Append ((byte) 3);
83 // Byte order of 4 byte ints
84 // 0 = <MSB, LSB>, 1 = <LSB, MSB>
85 Comm.Append ((byte) 1);
87 // Character representation
88 // (6 = ASCII, 7 = EBCDIC)
89 Comm.Append ((byte) 6);
91 // Eight byte floating point representation
92 // 4 = IEEE <MSB, ..., LSB>
94 // 10 = IEEE <LSB, ..., MSB>
96 Comm.Append ((byte) 10);
98 // Eight byte date format
99 // 8 = <MSB, ..., LSB>
100 Comm.Append ((byte) 9);
103 Comm.Append ((byte) 1);
105 // disallow dump/load and bulk insert
106 Comm.Append ((byte) 1);
108 // sql interface type
109 Comm.Append ((byte) 0);
111 // type of network connection
112 Comm.Append ((byte) 0);
116 Comm.Append (empty, 7, pad);
118 tmp = Comm.Append (connectionParameters.ApplicationName, 30, pad);
119 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
122 tmp = Comm.Append (DataSource, 30, pad);
123 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
126 Comm.Append (empty, 2, pad);
127 tmp = Comm.Append (connectionParameters.Password, 253, pad);
128 Comm.Append ((byte) (tmp.Length < 253 ? tmp.Length + 2 : 253 + 2));
131 Comm.Append ((byte) (((byte) Version) / 10));
132 Comm.Append ((byte) (((byte) Version) % 10));
133 Comm.Append ((byte) 0);
134 Comm.Append ((byte) 0);
137 tmp = Comm.Append (connectionParameters.ProgName, 10, pad);
138 Comm.Append ((byte) (tmp.Length < 10 ? tmp.Length : 10));
141 Comm.Append ((byte) 6);
143 // Tell the server we can handle SQLServer version 6
144 Comm.Append ((byte) 0);
146 // Send zero to tell the server we can't handle any other version
147 Comm.Append ((byte) 0);
148 Comm.Append ((byte) 0);
150 // auto convert short
151 Comm.Append ((byte) 0);
154 Comm.Append ((byte) 0x0d);
157 Comm.Append ((byte) 0x11);
160 tmp = Comm.Append (Language, 30, pad);
161 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
163 // notify on lang change
164 Comm.Append ((byte) 1);
166 // security label hierarchy
167 Comm.Append ((short) 0);
169 // security components
170 Comm.Append (empty, 8, pad);
173 Comm.Append ((short) 0);
175 // security login role
176 Comm.Append ((byte) 0);
179 tmp = Comm.Append (Charset, 30, pad);
180 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
182 // notify on charset change
183 Comm.Append ((byte) 1);
185 // length of tds packets
186 tmp = Comm.Append (PacketSize.ToString (), 6, pad);
187 Comm.Append ((byte) 3);
189 // pad out to a longword
190 Comm.Append (empty, 8, pad);
194 TdsPacketResult result;
198 result = ProcessSubPacket ();
199 done = (result is TdsPacketEndTokenResult);
204 protected override TdsPacketColumnInfoResult ProcessColumnInfo ()
208 int totalLength = Comm.GetTdsShort ();
211 TdsPacketColumnInfoResult result = new TdsPacketColumnInfoResult ();
213 while (bytesRead < totalLength) {
219 byte[] flagData = new byte[4];
220 for (int i = 0; i < 4; i += 1) {
221 flagData[i] = Comm.GetByte ();
224 bool nullable = (flagData[2] & 0x01) > 0;
225 bool caseSensitive = (flagData[2] & 0x02) > 0;
226 bool writable = (flagData[2] & 0x0c) > 0;
227 bool autoIncrement = (flagData[2] & 0x10) > 0;
229 string tableName = String.Empty;
230 TdsColumnType columnType = (TdsColumnType) Comm.GetByte ();
234 if (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image) {
238 int tableNameLength = Comm.GetTdsShort ();
240 tableName = Comm.GetString (tableNameLength);
241 bytesRead += tableNameLength;
242 bufLength = 2 << 31 - 1;
244 else if (columnType == TdsColumnType.Decimal || columnType == TdsColumnType.Numeric) {
245 bufLength = Comm.GetByte ();
247 precision = Comm.GetByte ();
249 scale = Comm.GetByte ();
252 else if (IsFixedSizeColumn (columnType))
253 bufLength = LookupBufferSize (columnType);
255 bufLength = (int) Comm.GetByte () & 0xff;
259 int index = result.Add (new TdsSchemaInfo ());
260 result[index].NumericPrecision = precision;
261 result[index].NumericScale = scale;
262 result[index].ColumnSize = bufLength;
263 result[index].ColumnName = ColumnNames[index];
264 result[index].ColumnType = columnType;
265 result[index].BaseTableName = tableName;
266 result[index].AllowDBNull = nullable;
267 result[index].IsReadOnly = !writable;
270 //int skipLength = totalLength - bytesRead;
271 //if (skipLength != 0)
272 //throw new TdsException ("skipping");
277 #endregion // Methods