byte GetScale(TdsColumnType type, int columnSize) { switch (type) { case TdsColumnType.DateTime: return(0x03); case TdsColumnType.DateTime4: return(0x00); case TdsColumnType.DateTimeN: switch (columnSize) { case 4: return(0x00); case 8: return(0x03); } break; default: return(0xff); } throw new NotSupportedException(string.Format( CultureInfo.InvariantCulture, "Fixed scale not defined for column " + "type '{0}' with size {1}.", type, columnSize)); }
private void GetSchemaRowDbType(TdsColumnType ctype, int csize, out int dbType) { Type fieldType; bool isLong; string typeName; GetSchemaRowType(ctype, csize, out dbType, out fieldType, out isLong, out typeName); }
private int GetDateTimeStringLength (TdsColumnType type) { int precision = GetDateTimePrecision (); int len = precision == 0 ? 19 : 20 + precision; if (type == TdsColumnType.DateTimeOffset) len += 6; return len; }
private void WriteParameterInfo(TdsMetaParameter param) { /* * Ms.net send non-nullable datatypes as nullable and allows setting null values * to int/float etc.. So, using Nullable form of type for all data */ param.IsNullable = true; TdsColumnType colType = param.GetMetaType(); param.IsNullable = false; tds.Comm.Append((byte)colType); // type int size = 0; if (param.Size == 0) { size = param.GetActualSize(); } else { size = param.Size; } /* * If column type is SqlDbType.NVarChar the size of parameter is multiplied by 2 * FIXME: Need to check for other types */ if (colType == TdsColumnType.BigNVarChar) { size <<= 1; } if (tds.IsLargeType(colType)) { tds.Comm.Append((short)size); // Parameter size passed in SqlParameter } else if (tds.IsBlobType(colType)) { tds.Comm.Append(size); // Parameter size passed in SqlParameter } else { tds.Comm.Append((byte)size); } // Precision and Scale are non-zero for only decimal/numeric if (param.TypeName == "decimal" || param.TypeName == "numeric") { tds.Comm.Append((param.Precision != 0)?param.Precision:(byte)29); tds.Comm.Append(param.Scale); } }
// HACK: Wire-level DateTime{2,Offset} require TDS // 7.3, which this driver does not implement // correctly--so we serialize to ASCII instead. private string GetDateTimeString (TdsColumnType type) { int precision = GetDateTimePrecision (); string fmt = "yyyy-MM-dd'T'HH':'mm':'ss"; if (precision > 0) fmt += ".fffffff".Substring(0, precision + 1); switch (type) { case TdsColumnType.DateTime2: DateTime dt = (DateTime)Value; return dt.ToString(fmt); case TdsColumnType.DateTimeOffset: DateTimeOffset dto = (DateTimeOffset)Value; return dto.ToString(fmt + "zzz"); } throw new ApplicationException("Should be unreachable"); }
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); }
protected override void ProcessColumnInfo() { int numColumns = Comm.GetTdsShort(); 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)); byte xColumnType = 0; if (IsLargeType(columnType)) { xColumnType = (byte)columnType; if (columnType != TdsColumnType.NChar) { columnType -= 128; } } int columnSize; string tableName = null; if (IsBlobType(columnType)) { columnSize = Comm.GetTdsInt(); tableName = Comm.GetString(Comm.GetTdsShort()); } else if (IsFixedSizeColumn(columnType)) { columnSize = LookupBufferSize(columnType); } else if (IsLargeType((TdsColumnType)xColumnType)) { columnSize = Comm.GetTdsShort(); } else { columnSize = Comm.GetByte() & 0xff; } if (IsWideType((TdsColumnType)columnType)) { columnSize /= 2; } byte precision = 0; byte scale = 0; if (columnType == TdsColumnType.Decimal || columnType == TdsColumnType.Numeric) { precision = Comm.GetByte(); scale = Comm.GetByte(); } else { precision = GetPrecision(columnType, columnSize); scale = GetScale(columnType, columnSize); } 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.DataTypeName = Enum.GetName(typeof(TdsColumnType), xColumnType); } }
internal static bool IsFixedSizeColumn (TdsColumnType columnType) { switch (columnType) { case TdsColumnType.Int1 : case TdsColumnType.Int2 : case TdsColumnType.Int4 : case TdsColumnType.Float8 : case TdsColumnType.DateTime : case TdsColumnType.Bit : case TdsColumnType.Money : case TdsColumnType.Money4 : case TdsColumnType.SmallMoney : case TdsColumnType.Real : case TdsColumnType.DateTime4 : return true; case TdsColumnType.IntN : case TdsColumnType.MoneyN : case TdsColumnType.VarChar : case TdsColumnType.NVarChar : case TdsColumnType.DateTimeN : case TdsColumnType.FloatN : case TdsColumnType.Char : case TdsColumnType.NChar : case TdsColumnType.NText : case TdsColumnType.Image : case TdsColumnType.VarBinary : case TdsColumnType.Binary : case TdsColumnType.Decimal : case TdsColumnType.Numeric : case TdsColumnType.BitN : case TdsColumnType.UniqueIdentifier : return false; default : return false; } }
protected override void ProcessColumnInfo() { byte precision; byte scale; int totalLength = Comm.GetTdsShort(); int bytesRead = 0; 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; } 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(); 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; } TdsDataColumn col = new TdsDataColumn(); int index = Columns.Add(col); #if NET_2_0 col.ColumnType = columnType; col.ColumnSize = bufLength; col.ColumnName = ColumnNames[index] as string; col.NumericPrecision = precision; col.NumericScale = scale; col.IsReadOnly = !writable; col.BaseTableName = tableName; col.AllowDBNull = nullable; #else col["ColumnType"] = columnType; col["ColumnSize"] = bufLength; col["ColumnName"] = ColumnNames[index]; col["NumericPrecision"] = precision; col["NumericScale"] = scale; col["IsReadOnly"] = !writable; col["BaseTableName"] = tableName; col["AllowDBNull"] = nullable; #endif } }
byte GetScale (TdsColumnType type, int columnSize) { switch (type) { case TdsColumnType.DateTime: return 0x03; case TdsColumnType.DateTime4: return 0x00; case TdsColumnType.DateTimeN: switch (columnSize) { case 4: return 0x00; case 8: return 0x03; } break; default: return 0xff; } throw new NotSupportedException (string.Format ( CultureInfo.InvariantCulture, "Fixed scale not defined for column " + "type '{0}' with size {1}.", type, columnSize)); }
private object GetIntValue (TdsColumnType type) { int len; switch (type) { case TdsColumnType.IntN : len = comm.GetByte (); break; case TdsColumnType.Int4 : len = 4; break; case TdsColumnType.Int2 : len = 2; break; case TdsColumnType.Int1 : len = 1; break; default: return DBNull.Value; } switch (len) { case 4 : return (comm.GetTdsInt ()); case 2 : return (comm.GetTdsShort ()); case 1 : return (comm.GetByte ()); default: return DBNull.Value; } }
private bool IsBlobType (TdsColumnType columnType) { return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText); }
long GetChars(int i, long dataIndex, char[] buffer, int bufferIndex, int length) { if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) { Encoding encoding = null; byte mul = 1; TdsColumnType colType = (TdsColumnType)command.Tds.Columns[i]["ColumnType"]; switch (colType) { case TdsColumnType.Text: case TdsColumnType.VarChar: case TdsColumnType.Char: case TdsColumnType.BigVarChar: encoding = Encoding.ASCII; break; case TdsColumnType.NText: case TdsColumnType.NVarChar: case TdsColumnType.NChar: encoding = Encoding.Unicode; mul = 2; break; default: return(-1); } long count = 0; if (buffer == null) { count = GetBytes(i, 0, (byte[])null, 0, 0); return(count / mul); } length *= mul; byte[] arr = new byte [length]; count = GetBytes(i, dataIndex, arr, 0, length); if (count == -1) { throw new InvalidCastException("Specified cast is not valid"); } Char[] val = encoding.GetChars(arr, 0, (int)count); val.CopyTo(buffer, bufferIndex); return(val.Length); } char [] valueBuffer; object value = GetValue(i); if (value is char[]) { valueBuffer = (char[])value; } else if (value is string) { valueBuffer = ((string)value).ToCharArray(); } else { if (value is DBNull) { throw new SqlNullValueException(); } throw new InvalidCastException("Type is " + value.GetType().ToString()); } if (buffer == null) { // Return length of data return(valueBuffer.Length); } else { // Copy data into buffer Array.Copy(valueBuffer, (int)dataIndex, buffer, bufferIndex, length); return(valueBuffer.Length - dataIndex); } }
protected object GetStringValue ( TdsColumnType? colType, bool wideChars, bool outputParam, Encoding encoder) { bool shortLen = false; Encoding enc = encoder; if (tdsVersion > TdsVersion.tds70 && outputParam && (colType == TdsColumnType.BigChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarChar || colType == TdsColumnType.NChar || colType == TdsColumnType.NVarChar)) { // Read collation for SqlServer 2000 and beyond byte[] collation; collation = Comm.GetBytes (5, true); enc = TdsCharset.GetEncoding (collation); shortLen = true; } else { shortLen = (tdsVersion >= TdsVersion.tds70) && (wideChars || !outputParam); } int len = shortLen ? comm.GetTdsShort () : (comm.GetByte () & 0xff); return GetStringValue (wideChars, len, enc); }
internal bool IsBlobType (TdsColumnType columnType) { return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText || columnType == TdsColumnType.Variant); }
private object GetIntValue ( TdsColumnType? type ) { int len; if (type == null) throw new ArgumentNullException ("type"); switch (type) { case TdsColumnType.BigInt : len = 8; break; case TdsColumnType.IntN : len = comm.GetByte (); break; case TdsColumnType.Int4 : len = 4; break; case TdsColumnType.Int2 : len = 2; break; case TdsColumnType.Int1 : len = 1; break; default: return DBNull.Value; } switch (len) { case 8: return (comm.GetTdsInt64 ()); case 4 : return (comm.GetTdsInt ()); case 2 : return (comm.GetTdsShort ()); case 1 : return (comm.GetByte ()); default: return DBNull.Value; } }
private object GetMoneyValue ( TdsColumnType? type ) { int len; if (type == null) throw new ArgumentNullException ("type"); switch (type) { case TdsColumnType.SmallMoney : case TdsColumnType.Money4 : len = 4; break; case TdsColumnType.Money : len = 8; break; case TdsColumnType.MoneyN : len = comm.GetByte (); break; default: return DBNull.Value; } switch (len) { case 4: { int val = Comm.GetTdsInt (); bool negative = val < 0; if (negative) val = ~(val - 1); return new Decimal (val, 0, 0, negative, 4); } case 8: { int hi = Comm.GetTdsInt (); int lo = Comm.GetTdsInt (); bool negative = hi < 0; if (negative) { hi = ~hi; lo = ~(lo - 1); } return new Decimal (lo, hi, 0, negative, 4); } default: return DBNull.Value; } }
private object GetFloatValue ( TdsColumnType? columnType ) { if (columnType == null) throw new ArgumentNullException ("columnType"); int columnSize = 0; switch (columnType) { case TdsColumnType.Real: columnSize = 4; break; case TdsColumnType.Float8: columnSize = 8; break; case TdsColumnType.FloatN: columnSize = comm.GetByte (); break; } switch (columnSize) { case 8 : return BitConverter.Int64BitsToDouble (comm.GetTdsInt64 ()); case 4 : return BitConverter.ToSingle (BitConverter.GetBytes (comm.GetTdsInt ()), 0); default : return DBNull.Value; } }
private object GetDateTimeValue ( TdsColumnType? type ) { int len = 0; object result; if (type == null) throw new ArgumentNullException ("type"); switch (type) { case TdsColumnType.DateTime4: len = 4; break; case TdsColumnType.DateTime: len = 8; break; case TdsColumnType.DateTimeN: byte tmp = comm.Peek (); if (tmp != 0 && tmp != 4 && tmp != 8) break; len = comm.GetByte (); break; } DateTime epoch = new DateTime (1900, 1, 1); switch (len) { case 8 : result = epoch.AddDays (comm.GetTdsInt ()); int seconds = comm.GetTdsInt (); long millis = (long) System.Math.Round (((((long) seconds) % 300L) * 1000L) / 300f); if (seconds != 0 || millis != 0) { result = ((DateTime) result).AddSeconds (seconds / 300); result = ((DateTime) result).AddMilliseconds (millis); } break; case 4 : // MSDN says small datetime is stored in 2 bytes as no of days // *after* 1/1/1900. so, cast to unsigned short result = epoch.AddDays ((ushort) comm.GetTdsShort ()); short minutes = comm.GetTdsShort (); if (minutes != 0) result = ((DateTime) result).AddMinutes ((int) minutes); break; default: result = DBNull.Value; break; } return result; }
private int LookupDisplaySize (TdsColumnType columnType) { switch (columnType) { case TdsColumnType.Int1 : return 3; case TdsColumnType.Int2 : return 6; case TdsColumnType.Int4 : return 11; case TdsColumnType.Real : return 14; case TdsColumnType.Float8 : return 24; case TdsColumnType.DateTime : return 23; case TdsColumnType.DateTime4 : return 16; case TdsColumnType.Bit : return 1; case TdsColumnType.Money : return 21; case TdsColumnType.Money4 : case TdsColumnType.SmallMoney : return 12; default: return 0; } }
private object GetColumnValue (TdsColumnType colType, bool outParam, int ordinal) { int len; object element = null; switch (colType) { case TdsColumnType.IntN : if (outParam) comm.Skip (1); element = GetIntValue (colType); break; case TdsColumnType.Int1 : case TdsColumnType.Int2 : case TdsColumnType.Int4 : element = GetIntValue (colType); break; case TdsColumnType.Image : if (outParam) comm.Skip (1); element = GetImageValue (); break; case TdsColumnType.Text : if (outParam) comm.Skip (1); element = GetTextValue (false); break; case TdsColumnType.NText : if (outParam) comm.Skip (1); element = GetTextValue (true); break; case TdsColumnType.Char : case TdsColumnType.VarChar : if (outParam) comm.Skip (1); element = GetStringValue (false, false); break; case TdsColumnType.BigVarBinary : comm.GetTdsShort (); len = comm.GetTdsShort (); element = comm.GetBytes (len, true); break; case TdsColumnType.BigVarChar : comm.Skip (2); element = GetStringValue (false, false); break; case TdsColumnType.NChar : case TdsColumnType.NVarChar : if (outParam) comm.Skip (1); element = GetStringValue (true, false); break; case TdsColumnType.Real : case TdsColumnType.Float8 : element = GetFloatValue (colType); break; case TdsColumnType.FloatN : if (outParam) comm.Skip (1); element = GetFloatValue (colType); break; case TdsColumnType.SmallMoney : case TdsColumnType.Money : element = GetMoneyValue (colType); break; case TdsColumnType.MoneyN : if (outParam) comm.Skip (1); element = GetMoneyValue (colType); break; case TdsColumnType.Numeric : case TdsColumnType.Decimal : byte precision; byte scale; if (outParam) { comm.Skip (1); precision = comm.GetByte (); scale = comm.GetByte (); } else { precision = (byte) columns[ordinal]["NumericPrecision"]; scale = (byte) columns[ordinal]["NumericScale"]; } element = GetDecimalValue (precision, scale); break; case TdsColumnType.DateTimeN : if (outParam) comm.Skip (1); element = GetDateTimeValue (colType); break; case TdsColumnType.DateTime4 : case TdsColumnType.DateTime : element = GetDateTimeValue (colType); break; case TdsColumnType.VarBinary : case TdsColumnType.Binary : if (outParam) comm.Skip (1); element = GetBinaryValue (); break; case TdsColumnType.BitN : if (outParam) comm.Skip (1); if (comm.GetByte () == 0) element = DBNull.Value; else element = (comm.GetByte() != 0); break; case TdsColumnType.Bit : int columnSize = comm.GetByte (); element = (columnSize != 0); break; case TdsColumnType.UniqueIdentifier : if (comm.Peek () != 16) { // If it's null, then what to do? /*byte swallowed =*/ comm.GetByte(); element = DBNull.Value; break; } len = comm.GetByte () & 0xff; if (len > 0) { byte[] guidBytes = comm.GetBytes (len, true); if (!BitConverter.IsLittleEndian) { byte[] swappedguidBytes = new byte[len]; for (int i = 0; i < 4; i++) swappedguidBytes[i] = guidBytes[4-i-1]; for (int i = 4; i < 6; i++) swappedguidBytes[i] = guidBytes[6-(i-4)-1]; for (int i = 6; i < 8; i++) swappedguidBytes[i] = guidBytes[8-(i-6)-1]; for (int i = 8; i < 16; i++) swappedguidBytes[i] = guidBytes[i]; Array.Copy(swappedguidBytes, 0, guidBytes, 0, len); } element = new Guid (guidBytes); } break; default : return DBNull.Value; } return element; }
internal bool IsLargeType (TdsColumnType columnType) { return ((byte) columnType > 128); }
private void WriteParameterInfo(TdsMetaParameter param) { /* * Ms.net send non-nullable datatypes as nullable and allows setting null values * to int/float etc.. So, using Nullable form of type for all data */ param.IsNullable = true; TdsColumnType colType = param.GetMetaType(); param.IsNullable = false; bool partLenType = false; int size = param.Size; if (size < 1) { if (size < 0) { partLenType = true; } size = param.GetActualSize(); } // Change colType according to the following table /* * Original Type Maxlen New Type * * NVarChar 4000 UCS2 NText * BigVarChar 8000 ASCII Text * BigVarBinary 8000 bytes Image * */ TdsColumnType origColType = colType; if (colType == TdsColumnType.BigNVarChar) { // param.GetActualSize() returns len*2 if (size == param.Size) { size <<= 1; } if ((size >> 1) > 4000) { colType = TdsColumnType.NText; } } else if (colType == TdsColumnType.BigVarChar) { if (size > 8000) { colType = TdsColumnType.Text; } } else if (colType == TdsColumnType.BigVarBinary) { if (size > 8000) { colType = TdsColumnType.Image; } } // Calculation of TypeInfo field /* * orig size value TypeInfo field * * >= 0 <= Maxlen origColType + content len * > Maxlen NewType as per above table + content len * -1 origColType + USHORTMAXLEN (0xFFFF) + content len (TDS 9) * */ // Write updated colType, iff partLenType == false if (TdsVersion > TdsVersion.tds81 && partLenType) { Comm.Append((byte)origColType); Comm.Append((short)-1); } else if (ServerTdsVersion > TdsVersion.tds70 && origColType == TdsColumnType.Decimal) { Comm.Append((byte)TdsColumnType.Numeric); } else { Comm.Append((byte)colType); } if (IsLargeType(colType)) { Comm.Append((short)size); // Parameter size passed in SqlParameter } else if (IsBlobType(colType)) { Comm.Append(size); // Parameter size passed in SqlParameter } else { Comm.Append((byte)size); } // Precision and Scale are non-zero for only decimal/numeric if (param.TypeName == "decimal" || param.TypeName == "numeric") { Comm.Append((param.Precision != 0) ? param.Precision : (byte)29); Comm.Append(param.Scale); } /* VARADHAN: TDS 8 Debugging */ /* * if (Collation != null) { * Console.WriteLine ("Collation is not null"); * Console.WriteLine ("Column Type: {0}", colType); * Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2], * Collation[3], Collation[4]); * } else { * Console.WriteLine ("Collation is null"); * } */ // Tds > 7.0 uses collation if (Collation != null && (colType == TdsColumnType.BigChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarChar || colType == TdsColumnType.NChar || colType == TdsColumnType.NVarChar || colType == TdsColumnType.Text || colType == TdsColumnType.NText)) { Comm.Append(Collation); } // LAMESPEC: size should be 0xFFFF for any bigvarchar, bignvarchar and bigvarbinary // types if param value is NULL if ((colType == TdsColumnType.BigVarChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarBinary) && (param.Value == null || param.Value == DBNull.Value)) { size = -1; } else { size = param.GetActualSize(); } if (IsLargeType(colType)) { Comm.Append((short)size); } else if (IsBlobType(colType)) { Comm.Append(size); } else { Comm.Append((byte)size); } if (size > 0) { switch (param.TypeName) { case "money": { Decimal val = (decimal)param.Value; int[] arr = Decimal.GetBits(val); if (val >= 0) { Comm.Append(arr[1]); Comm.Append(arr[0]); } else { Comm.Append(~arr[1]); Comm.Append(~arr[0] + 1); } break; } case "smallmoney": { Decimal val = (decimal)param.Value; if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX) { throw new OverflowException(string.Format( CultureInfo.InvariantCulture, "Value '{0}' is not valid for SmallMoney." + " Must be between {1:N4} and {2:N4}.", #if NET_2_0 val, #else val.ToString(CultureInfo.CurrentCulture), #endif SMALLMONEY_MIN, SMALLMONEY_MAX)); } int[] arr = Decimal.GetBits(val); int sign = (val > 0 ? 1: -1); Comm.Append(sign * arr[0]); break; } case "datetime": Comm.Append((DateTime)param.Value, 8); break; case "smalldatetime": Comm.Append((DateTime)param.Value, 4); break; case "varchar": case "nvarchar": case "char": case "nchar": case "text": case "ntext": byte [] tmp = param.GetBytes(); Comm.Append(tmp); break; case "uniqueidentifier": Comm.Append(((Guid)param.Value).ToByteArray()); break; default: Comm.Append(param.Value); break; } } return; }
protected bool IsWideType (TdsColumnType columnType) { switch (columnType) { case TdsColumnType.NChar: case TdsColumnType.NText: case TdsColumnType.NVarChar: return true; default: return false; } }
private bool IsLargeType (TdsColumnType columnType) { return (columnType == TdsColumnType.NChar || (byte) columnType > 128); }
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); #if NET_2_0 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; #else 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; #endif } //Console.WriteLine ("Tds80.cs: In ProcessColumnInfo... exit"); TDS 8 Debugging }
protected override void ProcessColumnInfo() { isSelectQuery = true; /*int totalLength = */ Comm.GetTdsShort(); int count = Comm.GetTdsShort(); for (int i = 0; i < count; i += 1) { string columnName = Comm.GetString(Comm.GetByte()); int status = Comm.GetByte(); bool hidden = (status & 0x01) > 0; bool isKey = (status & 0x02) > 0; bool isRowVersion = (status & 0x04) > 0; bool isUpdatable = (status & 0x10) > 0; bool allowDBNull = (status & 0x20) > 0; bool isIdentity = (status & 0x40) > 0; Comm.Skip(4); // User type byte type = Comm.GetByte(); bool isBlob = (type == 0x24); TdsColumnType columnType = (TdsColumnType)type; int bufLength = 0; byte precision = 0; byte scale = 0; if (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image) { bufLength = Comm.GetTdsInt(); Comm.Skip(Comm.GetTdsShort()); } else if (IsFixedSizeColumn(columnType)) { bufLength = LookupBufferSize(columnType); } else { //bufLength = Comm.GetTdsShort (); bufLength = Comm.GetByte(); } if (columnType == TdsColumnType.Decimal || columnType == TdsColumnType.Numeric) { precision = Comm.GetByte(); scale = Comm.GetByte(); } Comm.Skip(Comm.GetByte()); // Locale if (isBlob) { Comm.Skip(Comm.GetTdsShort()); // Class ID } TdsDataColumn col = new TdsDataColumn(); Columns.Add(col); col.ColumnType = columnType; col.ColumnName = columnName; col.IsIdentity = isIdentity; col.IsRowVersion = isRowVersion; col.ColumnType = columnType; col.ColumnSize = bufLength; col.NumericPrecision = precision; col.NumericScale = scale; col.IsReadOnly = !isUpdatable; col.IsKey = isKey; col.AllowDBNull = allowDBNull; col.IsHidden = hidden; } }
private void GetSchemaRowType(TdsColumnType ctype, int csize, out int dbType, out Type fieldType, out bool isLong, out string typeName) { dbType = -1; typeName = string.Empty; isLong = false; fieldType = typeof(Type); switch (ctype) { case TdsColumnType.Int1: case TdsColumnType.Int2: case TdsColumnType.Int4: case TdsColumnType.IntN: switch (csize) { case 1: typeName = "tinyint"; dbType = (int)SybaseType.TinyInt; fieldType = typeof(byte); isLong = false; break; case 2: typeName = "smallint"; dbType = (int)SybaseType.SmallInt; fieldType = typeof(short); isLong = false; break; case 4: typeName = "int"; dbType = (int)SybaseType.Int; fieldType = typeof(int); isLong = false; break; case 8: typeName = "bigint"; dbType = (int)SybaseType.BigInt; fieldType = typeof(long); isLong = false; break; } break; case TdsColumnType.Real: case TdsColumnType.Float8: case TdsColumnType.FloatN: switch (csize) { case 4: typeName = "real"; dbType = (int)SybaseType.Real; fieldType = typeof(float); isLong = false; break; case 8: typeName = "float"; dbType = (int)SybaseType.Float; fieldType = typeof(double); isLong = false; break; } break; case TdsColumnType.Image: typeName = "image"; dbType = (int)SybaseType.Image; fieldType = typeof(byte[]); isLong = true; break; case TdsColumnType.Text: typeName = "text"; dbType = (int)SybaseType.Text; fieldType = typeof(string); isLong = true; break; case TdsColumnType.UniqueIdentifier: typeName = "uniqueidentifier"; dbType = (int)SybaseType.UniqueIdentifier; fieldType = typeof(Guid); isLong = false; break; case TdsColumnType.VarBinary: case TdsColumnType.BigVarBinary: typeName = "varbinary"; dbType = (int)SybaseType.VarBinary; fieldType = typeof(byte[]); isLong = true; break; case TdsColumnType.VarChar: case TdsColumnType.BigVarChar: typeName = "varchar"; dbType = (int)SybaseType.VarChar; fieldType = typeof(string); isLong = false; break; case TdsColumnType.Binary: case TdsColumnType.BigBinary: typeName = "binary"; dbType = (int)SybaseType.Binary; fieldType = typeof(byte[]); isLong = true; break; case TdsColumnType.Char: case TdsColumnType.BigChar: typeName = "char"; dbType = (int)SybaseType.Char; fieldType = typeof(string); isLong = false; break; case TdsColumnType.Bit: case TdsColumnType.BitN: typeName = "bit"; dbType = (int)SybaseType.Bit; fieldType = typeof(bool); isLong = false; break; case TdsColumnType.DateTime4: case TdsColumnType.DateTime: case TdsColumnType.DateTimeN: typeName = "datetime"; dbType = (int)SybaseType.DateTime; fieldType = typeof(DateTime); isLong = false; break; case TdsColumnType.Money: case TdsColumnType.MoneyN: case TdsColumnType.Money4: typeName = "money"; dbType = (int)SybaseType.Money; fieldType = typeof(decimal); isLong = false; break; case TdsColumnType.NText: typeName = "ntext"; dbType = (int)SybaseType.NText; fieldType = typeof(string); isLong = true; break; case TdsColumnType.NVarChar: typeName = "nvarchar"; dbType = (int)SybaseType.NVarChar; fieldType = typeof(string); isLong = false; break; case TdsColumnType.Decimal: case TdsColumnType.Numeric: typeName = "decimal"; dbType = (int)SybaseType.Decimal; fieldType = typeof(decimal); isLong = false; break; case TdsColumnType.NChar: typeName = "nchar"; dbType = (int)SybaseType.NChar; fieldType = typeof(string); isLong = false; break; case TdsColumnType.SmallMoney: typeName = "smallmoney"; dbType = (int)SybaseType.SmallMoney; fieldType = typeof(decimal); isLong = false; break; default: typeName = "variant"; dbType = (int)SybaseType.Variant; fieldType = typeof(object); isLong = false; break; } }
byte GetPrecision (TdsColumnType type, int columnSize) { switch (type) { case TdsColumnType.Binary: return 0xff; case TdsColumnType.Bit: return 0xff; case TdsColumnType.Char: return 0xff; case TdsColumnType.DateTime: return 0x17; case TdsColumnType.DateTime4: return 0x10; case TdsColumnType.DateTimeN: switch (columnSize) { case 4: return 0x10; case 8: return 0x17; } break; case TdsColumnType.Real: return 0x07; case TdsColumnType.Float8: return 0x0f; case TdsColumnType.FloatN: switch (columnSize) { case 4: return 0x07; case 8: return 0x0f; } break; case TdsColumnType.Image: return 0xff; case TdsColumnType.Int1: return 0x03; case TdsColumnType.Int2: return 0x05; case TdsColumnType.Int4: return 0x0a; case TdsColumnType.IntN: switch (columnSize) { case 1: return 0x03; case 2: return 0x05; case 4: return 0x0a; } break; case TdsColumnType.Void: return 0x01; case TdsColumnType.Text: return 0xff; case TdsColumnType.UniqueIdentifier: return 0xff; case TdsColumnType.VarBinary: return 0xff; case TdsColumnType.VarChar: return 0xff; case TdsColumnType.Money: return 19; case TdsColumnType.NText: return 0xff; case TdsColumnType.NVarChar: return 0xff; case TdsColumnType.BitN: return 0xff; case TdsColumnType.MoneyN: switch (columnSize) { case 4: return 0x0a; case 8: return 0x13; } break; case TdsColumnType.Money4: return 0x0a; case TdsColumnType.NChar: return 0xff; case TdsColumnType.BigBinary: return 0xff; case TdsColumnType.BigVarBinary: return 0xff; case TdsColumnType.BigVarChar: return 0xff; case TdsColumnType.BigNVarChar: return 0xff; case TdsColumnType.BigChar: return 0xff; case TdsColumnType.SmallMoney: return 0x0a; case TdsColumnType.Variant: return 0xff; case TdsColumnType.BigInt: return 0xff; } throw new NotSupportedException (string.Format ( CultureInfo.InvariantCulture, "Fixed precision not defined for column " + "type '{0}' with size {1}.", type, columnSize)); }
private SqlDbType GetSchemaRowDbType (TdsColumnType ctype, int csize, short precision, short scale) { Type fieldType; bool isLong; string typeName; int dbType; GetSchemaRowType (ctype, csize, precision, scale, out dbType, out fieldType, out isLong, out typeName); return (SqlDbType) dbType; }
internal static bool IsFixedSizeColumn (TdsColumnType columnType) { switch (columnType) { case TdsColumnType.Int1 : case TdsColumnType.Int2 : case TdsColumnType.Int4 : case TdsColumnType.BigInt : case TdsColumnType.Float8 : case TdsColumnType.DateTime : case TdsColumnType.Bit : case TdsColumnType.Money : case TdsColumnType.Money4 : case TdsColumnType.SmallMoney : case TdsColumnType.Real : case TdsColumnType.DateTime4 : /* case TdsColumnType.Decimal: case TdsColumnType.Numeric: */ return true; default : return false; } }
private object GetMoneyValue (TdsColumnType type) { int len; object result = null; switch (type) { case TdsColumnType.SmallMoney : case TdsColumnType.Money4 : len = 4; break; case TdsColumnType.Money : len = 8; break; case TdsColumnType.MoneyN : len = comm.GetByte (); break; default: return DBNull.Value; } long rawValue = 0; switch (len) { case 4: rawValue = comm.GetTdsInt (); break; case 8: byte[] bits = new byte[8]; bits[4] = comm.GetByte (); bits[5] = comm.GetByte (); bits[6] = comm.GetByte (); bits[7] = comm.GetByte (); bits[0] = comm.GetByte (); bits[1] = comm.GetByte (); bits[2] = comm.GetByte (); bits[3] = comm.GetByte (); rawValue = BitConverter.ToInt64 (bits, 0); break; default: return DBNull.Value; } result = new Decimal (rawValue); return (((decimal) result) / 10000); }
internal string Prepare() { string typeName = TypeName; // Cf. GetDateTimeString TdsColumnType actualType = TdsColumnType.Char; int size; switch (typeName) { case "varbinary": size = Size; if (size <= 0) { size = GetActualSize(); } if (size > 8000) { typeName = "varbinary(max)"; } break; case "datetime2": actualType = TdsColumnType.DateTime2; typeName = "char"; break; case "datetimeoffset": actualType = TdsColumnType.DateTimeOffset; typeName = "char"; break; } string includeAt = "@"; if (ParameterName[0] == '@') { includeAt = ""; } StringBuilder result = new StringBuilder(String.Format("{0}{1} {2}", includeAt, ParameterName, typeName)); switch (typeName) { case "decimal": case "numeric": // msdotnet sends a default precision of 29 result.Append(String.Format("({0},{1})", (Precision == (byte)0 ? (byte)38 : Precision), Scale)); break; case "varchar": case "varbinary": //A size of 0 is not allowed in declarations. size = Size; if (size <= 0) { size = GetActualSize(); if (size <= 0) { size = 1; } } result.Append(size > 8000 ? "(max)" : String.Format("({0})", size)); break; case "nvarchar": int paramSize = Size < 0 ? GetActualSize() / 2 : Size; result.Append(paramSize > 0 ? (paramSize > 4000 ? "(max)" : String.Format("({0})", paramSize)) : "(4000)"); break; case "char": size = -1; if (actualType != TdsColumnType.Char) { size = GetDateTimeStringLength(actualType); } else if (isSizeSet) { size = Size; } if (size > 0) { result.Append(String.Format("({0})", size)); } break; case "nchar": case "binary": if (isSizeSet && Size > 0) { result.Append(String.Format("({0})", Size)); } break; } return(result.ToString()); }
internal static int LookupBufferSize (TdsColumnType columnType) { switch (columnType) { case TdsColumnType.Int1 : case TdsColumnType.Bit : return 1; case TdsColumnType.Int2 : return 2; case TdsColumnType.Int4 : case TdsColumnType.Real : case TdsColumnType.DateTime4 : case TdsColumnType.Money4 : case TdsColumnType.SmallMoney : return 4; case TdsColumnType.Float8 : case TdsColumnType.DateTime : case TdsColumnType.Money : case TdsColumnType.BigInt : return 8; default : return 0; } }
private void GetSchemaRowDbType (TdsColumnType ctype, int csize, out int dbType) { Type fieldType; bool isLong; string typeName; GetSchemaRowType (ctype, csize, out dbType, out fieldType, out isLong, out typeName); }
private void BeginLoad ( TdsColumnType? colType ) { if (LoadInProgress) EndLoad (); StreamLength = 0; if (colType == null) throw new ArgumentNullException ("colType"); switch (colType) { case TdsColumnType.Text : case TdsColumnType.NText: case TdsColumnType.Image: if (Comm.GetByte () != 0) { Comm.Skip (24); StreamLength = Comm.GetTdsInt (); } else { // use -2 to indicate that we're dealing // with a NULL value StreamLength = -2; } break; case TdsColumnType.BigVarChar: case TdsColumnType.BigChar: case TdsColumnType.BigBinary: case TdsColumnType.BigVarBinary: Comm.GetTdsShort (); StreamLength = Comm.GetTdsShort (); break; case TdsColumnType.VarChar : case TdsColumnType.NVarChar : case TdsColumnType.Char: case TdsColumnType.NChar: case TdsColumnType.Binary: case TdsColumnType.VarBinary: StreamLength = Comm.GetTdsShort (); break; default : StreamLength = -1; break; } StreamIndex = 0; LoadInProgress = true; }
private void GetSchemaRowType (TdsColumnType ctype, int csize, short precision, short scale, out int dbType, out Type fieldType, out bool isLong, out string typeName) { dbType = -1; typeName = string.Empty; isLong = false; fieldType = typeof (Type); switch (ctype) { case TdsColumnType.Int1: case TdsColumnType.Int2: case TdsColumnType.Int4: case TdsColumnType.IntN: case TdsColumnType.BigInt: switch (csize) { case 1: typeName = "tinyint"; dbType = (int) SqlDbType.TinyInt; fieldType = typeof (byte); isLong = false; break; case 2: typeName = "smallint"; dbType = (int) SqlDbType.SmallInt; fieldType = typeof (short); isLong = false; break; case 4: typeName = "int"; dbType = (int) SqlDbType.Int; fieldType = typeof (int); isLong = false; break; case 8: typeName = "bigint"; dbType = (int) SqlDbType.BigInt; fieldType = typeof (long); isLong = false; break; } break; case TdsColumnType.Real: case TdsColumnType.Float8: case TdsColumnType.FloatN: switch (csize) { case 4: typeName = "real"; dbType = (int) SqlDbType.Real; fieldType = typeof (float); isLong = false; break; case 8: typeName = "float"; dbType = (int) SqlDbType.Float; fieldType = typeof (double); isLong = false; break; } break; case TdsColumnType.Image : typeName = "image"; dbType = (int) SqlDbType.Image; fieldType = typeof (byte[]); isLong = true; break; case TdsColumnType.Text : typeName = "text"; dbType = (int) SqlDbType.Text; fieldType = typeof (string); isLong = true; break; case TdsColumnType.UniqueIdentifier : typeName = "uniqueidentifier"; dbType = (int) SqlDbType.UniqueIdentifier; fieldType = typeof (Guid); isLong = false; break; case TdsColumnType.VarBinary : case TdsColumnType.BigVarBinary : typeName = "varbinary"; dbType = (int) SqlDbType.VarBinary; fieldType = typeof (byte[]); isLong = false; break; case TdsColumnType.VarChar : case TdsColumnType.BigVarChar : typeName = "varchar"; dbType = (int) SqlDbType.VarChar; fieldType = typeof (string); isLong = false; break; case TdsColumnType.Binary : case TdsColumnType.BigBinary : typeName = "binary"; dbType = (int) SqlDbType.Binary; fieldType = typeof (byte[]); isLong = false; break; case TdsColumnType.Char : case TdsColumnType.BigChar : typeName = "char"; dbType = (int) SqlDbType.Char; fieldType = typeof (string); isLong = false; break; case TdsColumnType.Bit : case TdsColumnType.BitN : typeName = "bit"; dbType = (int) SqlDbType.Bit; fieldType = typeof (bool); isLong = false; break; case TdsColumnType.DateTime4 : case TdsColumnType.DateTime : case TdsColumnType.DateTimeN : switch (csize) { case 4: typeName = "smalldatetime"; dbType = (int) SqlDbType.SmallDateTime; fieldType = typeof (DateTime); isLong = false; break; case 8: typeName = "datetime"; dbType = (int) SqlDbType.DateTime; fieldType = typeof (DateTime); isLong = false; break; } break; case TdsColumnType.Money : case TdsColumnType.MoneyN : case TdsColumnType.Money4 : switch (csize) { case 4: typeName = "smallmoney"; dbType = (int) SqlDbType.SmallMoney; fieldType = typeof (decimal); isLong = false; break; case 8: typeName = "money"; dbType = (int) SqlDbType.Money; fieldType = typeof (decimal); isLong = false; break; } break; case TdsColumnType.NText : typeName = "ntext"; dbType = (int) SqlDbType.NText; fieldType = typeof (string); isLong = true; break; case TdsColumnType.NVarChar : typeName = "nvarchar"; dbType = (int) SqlDbType.NVarChar; fieldType = typeof (string); isLong = false; break; case TdsColumnType.Decimal : case TdsColumnType.Numeric : // TDS 7.0 returns bigint as decimal(19,0) if (precision == 19 && scale == 0) { typeName = "bigint"; dbType = (int) SqlDbType.BigInt; fieldType = typeof (long); } else { typeName = "decimal"; dbType = (int) SqlDbType.Decimal; fieldType = typeof (decimal); } isLong = false; break; case TdsColumnType.NChar : typeName = "nchar"; dbType = (int) SqlDbType.NChar; fieldType = typeof (string); isLong = false; break; case TdsColumnType.SmallMoney : typeName = "smallmoney"; dbType = (int) SqlDbType.SmallMoney; fieldType = typeof (decimal); isLong = false; break; default : typeName = "variant"; dbType = (int) SqlDbType.Variant; fieldType = typeof (object); isLong = false; break; } }
protected object GetColumnValue ( TdsColumnType? colType, bool outParam) { return GetColumnValue (colType, outParam, -1); }
private void BeginLoad ( #if NET_2_0 TdsColumnType? colType
byte GetPrecision(TdsColumnType type, int columnSize) { switch (type) { case TdsColumnType.Binary: return(0xff); case TdsColumnType.Bit: return(0xff); case TdsColumnType.Char: return(0xff); case TdsColumnType.DateTime: return(0x17); case TdsColumnType.DateTime4: return(0x10); case TdsColumnType.DateTimeN: switch (columnSize) { case 4: return(0x10); case 8: return(0x17); } break; case TdsColumnType.Real: return(0x07); case TdsColumnType.Float8: return(0x0f); case TdsColumnType.FloatN: switch (columnSize) { case 4: return(0x07); case 8: return(0x0f); } break; case TdsColumnType.Image: return(0xff); case TdsColumnType.Int1: return(0x03); case TdsColumnType.Int2: return(0x05); case TdsColumnType.Int4: return(0x0a); case TdsColumnType.IntN: switch (columnSize) { case 1: return(0x03); case 2: return(0x05); case 4: return(0x0a); } break; case TdsColumnType.Void: return(0x01); case TdsColumnType.Text: return(0xff); case TdsColumnType.UniqueIdentifier: return(0xff); case TdsColumnType.VarBinary: return(0xff); case TdsColumnType.VarChar: return(0xff); case TdsColumnType.Money: return(19); case TdsColumnType.NText: return(0xff); case TdsColumnType.NVarChar: return(0xff); case TdsColumnType.BitN: return(0xff); case TdsColumnType.MoneyN: switch (columnSize) { case 4: return(0x0a); case 8: return(0x13); } break; case TdsColumnType.Money4: return(0x0a); case TdsColumnType.NChar: return(0xff); case TdsColumnType.BigBinary: return(0xff); case TdsColumnType.BigVarBinary: return(0xff); case TdsColumnType.BigVarChar: return(0xff); case TdsColumnType.BigNVarChar: return(0xff); case TdsColumnType.BigChar: return(0xff); case TdsColumnType.SmallMoney: return(0x0a); case TdsColumnType.Variant: return(0xff); case TdsColumnType.BigInt: return(0xff); } throw new NotSupportedException(string.Format( CultureInfo.InvariantCulture, "Fixed precision not defined for column " + "type '{0}' with size {1}.", type, columnSize)); }
private object GetColumnValue ( TdsColumnType? colType, bool outParam, int ordinal) { int len; object element = null; Encoding enc = null; int lcid = 0, sortId = 0; if (colType == null) throw new ArgumentNullException ("colType"); if (ordinal > -1 && tdsVersion > TdsVersion.tds70) { lcid = (int) columns[ordinal].LCID; sortId = (int) columns[ordinal].SortOrder; } switch (colType) { case TdsColumnType.Variant: /* sql variant max size */ Comm.GetTdsInt (); byte type = Comm.GetByte (); byte propbyte = Comm.GetByte (); TdsColumnType realType = (TdsColumnType)(type & 0xff); if (realType == TdsColumnType.NVarChar || realType == TdsColumnType.BigNVarChar || realType == TdsColumnType.VarChar || realType == TdsColumnType.BigVarChar) { byte[] collation = null; collation = Comm.GetBytes (5, true); lcid = TdsCollation.LCID (collation); sortId = TdsCollation.SortId (collation); #if NET_2_0 columns[ordinal].LCID = lcid; columns[ordinal].SortOrder = sortId; #else columns[ordinal]["LCID"] = lcid; columns[ordinal]["SortOrder"] = sortId; #endif } element = GetColumnValue ((TdsColumnType)type, outParam, ordinal); break; case TdsColumnType.IntN : if (outParam) comm.Skip (1); element = GetIntValue (colType); break; case TdsColumnType.Int1 : case TdsColumnType.Int2 : case TdsColumnType.Int4 : case TdsColumnType.BigInt : element = GetIntValue (colType); break; case TdsColumnType.Image : if (outParam) comm.Skip (1); element = GetImageValue (); break; case TdsColumnType.Text : enc = GetEncodingFromColumnCollation (lcid, sortId); if (outParam) comm.Skip (1); element = GetTextValue (false, enc); break; case TdsColumnType.NText : enc = GetEncodingFromColumnCollation (lcid, sortId); if (outParam) comm.Skip (1); element = GetTextValue (true, enc); break; case TdsColumnType.Char : case TdsColumnType.VarChar : enc = GetEncodingFromColumnCollation (lcid, sortId); if (outParam) comm.Skip (1); element = GetStringValue (colType, false, outParam, enc); break; case TdsColumnType.BigVarBinary : if (outParam) comm.Skip (1); len = comm.GetTdsShort (); element = comm.GetBytes (len, true); break; /* case TdsColumnType.BigBinary : if (outParam) comm.Skip (2); len = comm.GetTdsShort (); element = comm.GetBytes (len, true); break; */ case TdsColumnType.BigBinary : if (outParam) comm.Skip (2); element = GetBinaryValue (); break; case TdsColumnType.BigChar : case TdsColumnType.BigVarChar : enc = GetEncodingFromColumnCollation (lcid, sortId); if (outParam) comm.Skip (2); element = GetStringValue (colType, false, outParam, enc); break; case TdsColumnType.NChar : case TdsColumnType.BigNVarChar : enc = GetEncodingFromColumnCollation (lcid, sortId); if (outParam) comm.Skip(2); element = GetStringValue (colType, true, outParam, enc); break; case TdsColumnType.NVarChar : enc = GetEncodingFromColumnCollation (lcid, sortId); if (outParam) comm.Skip (1); element = GetStringValue (colType, true, outParam, enc); break; case TdsColumnType.Real : case TdsColumnType.Float8 : element = GetFloatValue (colType); break; case TdsColumnType.FloatN : if (outParam) comm.Skip (1); element = GetFloatValue (colType); break; case TdsColumnType.SmallMoney : case TdsColumnType.Money : element = GetMoneyValue (colType); break; case TdsColumnType.MoneyN : if (outParam) comm.Skip (1); element = GetMoneyValue (colType); break; case TdsColumnType.Numeric : case TdsColumnType.Decimal : byte precision; byte scale; if (outParam) { comm.Skip (1); precision = comm.GetByte (); scale = comm.GetByte (); } else { precision = (byte) columns[ordinal].NumericPrecision; scale = (byte) columns[ordinal].NumericScale; } element = GetDecimalValue (precision, scale); // workaround for fact that TDS 7.0 returns // bigint as decimal (19,0), and client code // expects it to be returned as a long if (scale == 0 && precision <= 19 && tdsVersion == TdsVersion.tds70) { if (!(element is System.DBNull)) element = Convert.ToInt64 (element); } break; case TdsColumnType.DateTimeN : if (outParam) comm.Skip (1); element = GetDateTimeValue (colType); break; case TdsColumnType.DateTime4 : case TdsColumnType.DateTime : element = GetDateTimeValue (colType); break; case TdsColumnType.VarBinary : case TdsColumnType.Binary : if (outParam) comm.Skip (1); element = GetBinaryValue (); break; case TdsColumnType.BitN : if (outParam) comm.Skip (1); if (comm.GetByte () == 0) element = DBNull.Value; else element = (comm.GetByte() != 0); break; case TdsColumnType.Bit : int columnSize = comm.GetByte (); element = (columnSize != 0); break; case TdsColumnType.UniqueIdentifier : if (comm.Peek () != 16) { // If it's null, then what to do? /*byte swallowed =*/ comm.GetByte(); element = DBNull.Value; break; } if (outParam) comm.Skip (1); len = comm.GetByte () & 0xff; if (len > 0) { byte[] guidBytes = comm.GetBytes (len, true); if (!BitConverter.IsLittleEndian) { byte[] swappedguidBytes = new byte[len]; for (int i = 0; i < 4; i++) swappedguidBytes[i] = guidBytes[4-i-1]; for (int i = 4; i < 6; i++) swappedguidBytes[i] = guidBytes[6-(i-4)-1]; for (int i = 6; i < 8; i++) swappedguidBytes[i] = guidBytes[8-(i-6)-1]; for (int i = 8; i < 16; i++) swappedguidBytes[i] = guidBytes[i]; Array.Copy(swappedguidBytes, 0, guidBytes, 0, len); } element = new Guid (guidBytes); } break; case TdsColumnType.Variant : if (outParam) comm.Skip (4); element = GetVariantValue(); break; default : return DBNull.Value; } return element; }
private object GetColumnValue (TdsColumnType colType, bool outParam) { return GetColumnValue (colType, outParam, -1); }
private void WriteParameterInfo(TdsMetaParameter param) { /* * Ms.net send non-nullable datatypes as nullable and allows setting null values * to int/float etc.. So, using Nullable form of type for all data */ param.IsNullable = true; TdsColumnType colType = param.GetMetaType(); param.IsNullable = false; bool partLenType = false; int size = param.Size; if (size < 1) { if (size < 0) { partLenType = true; } size = param.GetActualSize(); } /* * If the value is null, not setting the size to 0 will cause varchar * fields to get inserted as an empty string rather than an null. */ if (param.IsTextType && (param.Value == null || param.Value == DBNull.Value)) { size = 0; } // Change colType according to the following table /* * Original Type Maxlen New Type * * NVarChar 4000 UCS2 NText * BigVarChar 8000 ASCII Text * BigVarBinary 8000 bytes Image * */ TdsColumnType origColType = colType; if (colType == TdsColumnType.BigNVarChar) { // param.GetActualSize() returns len*2 if (size == param.Size) { size <<= 1; } if ((size >> 1) > 4000) { colType = TdsColumnType.NText; } } else if (colType == TdsColumnType.BigVarChar) { if (size > 8000) { colType = TdsColumnType.Text; } } else if (colType == TdsColumnType.BigVarBinary) { if (size > 8000) { colType = TdsColumnType.Image; } } else if (colType == TdsColumnType.DateTime2 || colType == TdsColumnType.DateTimeOffset) { // HACK: Wire-level DateTime{2,Offset} // require TDS 7.3, which this driver // does not implement correctly--so we // serialize to ASCII instead. colType = TdsColumnType.Char; } // Calculation of TypeInfo field /* * orig size value TypeInfo field * * >= 0 <= Maxlen origColType + content len * > Maxlen NewType as per above table + content len * -1 origColType + USHORTMAXLEN (0xFFFF) + content len (TDS 9) * */ // Write updated colType, iff partLenType == false if (TdsVersion > TdsVersion.tds81 && partLenType) { Comm.Append((byte)origColType); Comm.Append((short)-1); } else if (ServerTdsVersion > TdsVersion.tds70 && origColType == TdsColumnType.Decimal) { Comm.Append((byte)TdsColumnType.Numeric); } else { Comm.Append((byte)colType); } if (IsLargeType(colType)) { Comm.Append((short)size); // Parameter size passed in SqlParameter } else if (IsBlobType(colType)) { Comm.Append(size); // Parameter size passed in SqlParameter } else { Comm.Append((byte)size); } // Precision and Scale are non-zero for only decimal/numeric if (param.TypeName == "decimal" || param.TypeName == "numeric") { Comm.Append((param.Precision != 0) ? param.Precision : Precision); Comm.Append(param.Scale); // Convert the decimal value according to Scale if (param.Value != null && param.Value != DBNull.Value && ((decimal)param.Value) != Decimal.MaxValue && ((decimal)param.Value) != Decimal.MinValue && ((decimal)param.Value) != long.MaxValue && ((decimal)param.Value) != long.MinValue && ((decimal)param.Value) != ulong.MaxValue && ((decimal)param.Value) != ulong.MinValue) { long expo = (long)new Decimal(System.Math.Pow(10, (double)param.Scale)); long pVal = (long)(((decimal)param.Value) * expo); param.Value = pVal; } } /* VARADHAN: TDS 8 Debugging */ /* * if (Collation != null) { * Console.WriteLine ("Collation is not null"); * Console.WriteLine ("Column Type: {0}", colType); * Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2], * Collation[3], Collation[4]); * } else { * Console.WriteLine ("Collation is null"); * } */ // Tds > 7.0 uses collation if (Collation != null && (colType == TdsColumnType.BigChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarChar || colType == TdsColumnType.NChar || colType == TdsColumnType.NVarChar || colType == TdsColumnType.Text || colType == TdsColumnType.NText)) { Comm.Append(Collation); } // LAMESPEC: size should be 0xFFFF for any bigvarchar, bignvarchar and bigvarbinary // types if param value is NULL if ((colType == TdsColumnType.BigVarChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarBinary || colType == TdsColumnType.Image) && (param.Value == null || param.Value == DBNull.Value)) { size = -1; } else { size = param.GetActualSize(); } if (IsLargeType(colType)) { Comm.Append((short)size); } else if (IsBlobType(colType)) { Comm.Append(size); } else { Comm.Append((byte)size); } if (size > 0) { switch (param.TypeName) { case "money": { // 4 == SqlMoney::MoneyFormat.NumberDecimalDigits Decimal val = Decimal.Round((decimal)param.Value, 4); int[] arr = Decimal.GetBits(val); if (val >= 0) { Comm.Append(arr[1]); Comm.Append(arr[0]); } else { Comm.Append(~arr[1]); Comm.Append(~arr[0] + 1); } break; } case "smallmoney": { // 4 == SqlMoney::MoneyFormat.NumberDecimalDigits Decimal val = Decimal.Round((decimal)param.Value, 4); if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX) { throw new OverflowException(string.Format( CultureInfo.InvariantCulture, "Value '{0}' is not valid for SmallMoney." + " Must be between {1:N4} and {2:N4}.", val, SMALLMONEY_MIN, SMALLMONEY_MAX)); } int[] arr = Decimal.GetBits(val); int sign = (val > 0 ? 1: -1); Comm.Append(sign * arr[0]); break; } case "datetime": Comm.Append((DateTime)param.Value, 8); break; case "smalldatetime": Comm.Append((DateTime)param.Value, 4); break; case "varchar": case "nvarchar": case "char": case "nchar": case "text": case "ntext": case "datetime2": case "datetimeoffset": byte [] tmp = param.GetBytes(); Comm.Append(tmp); break; case "uniqueidentifier": Comm.Append(((Guid)param.Value).ToByteArray()); break; default: Comm.Append(param.Value); break; } } return; }
private void WriteParameterInfo(TdsMetaParameter param) { TdsColumnType colType = param.GetMetaType(); int size = 0; if (param.Size == 0) { size = param.GetActualSize(); } else { size = param.Size; } /* * If column type is SqlDbType.NVarChar the size of parameter is multiplied by 2 * FIXME: Need to check for other types */ if (colType == TdsColumnType.BigNVarChar) { size <<= 1; } // Total hack for varchar(max) and nvarchar(max) // They are coming back as Text and not the correct values // based on the size we can determine what the correct type is // We need the size to come out to 0xFFFF on the wire. if (param.IsVarNVarCharMax) { colType = TdsColumnType.BigNVarChar; } else if (param.IsVarCharMax) { colType = TdsColumnType.BigVarChar; } tds.Comm.Append((byte)colType); // type param.CalculateIsVariableType(); if (param.IsAnyVarCharMax) { tds.Comm.Append((byte)0xFF); tds.Comm.Append((byte)0xFF); } else if (tds.IsLargeType(colType)) { tds.Comm.Append((short)size); // Parameter size passed in SqlParameter } else if (tds.IsBlobType(colType)) { tds.Comm.Append(size); // Parameter size passed in SqlParameter } else if (param.IsVariableSizeType) { tds.Comm.Append((byte)size); } // Precision and Scale are non-zero for only decimal/numeric if (param.TypeName == "decimal" || param.TypeName == "numeric") { tds.Comm.Append((param.Precision != 0)?param.Precision:(byte)29); tds.Comm.Append(param.Scale); } // Documentation is basically 0 on these 5 bytes. But in a nutshell it seems during a bulk insert // these are required for text types. if (param.IsTextType) { tds.Comm.Append((byte)0x09); tds.Comm.Append((byte)0x04); tds.Comm.Append((byte)0xd0); tds.Comm.Append((byte)0x00); tds.Comm.Append((byte)0x34); } }