Пример #1
0
        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));
        }
Пример #2
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);
        }
Пример #3
0
		private int GetDateTimeStringLength (TdsColumnType type)
		{
			int precision = GetDateTimePrecision ();
			int len = precision == 0 ? 19 : 20 + precision;

			if (type == TdsColumnType.DateTimeOffset)
				len += 6;

			return len;
		}
Пример #4
0
        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);
            }
        }
Пример #5
0
		// 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");
		}
Пример #6
0
        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);
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
		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;
			}
		}
Пример #9
0
        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
            }
        }
Пример #10
0
		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));
		}
Пример #11
0
		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;
			}
		}
Пример #12
0
                private bool IsBlobType (TdsColumnType columnType)
		{
			return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText);
		}
Пример #13
0
        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);
            }
        }
Пример #14
0
Файл: Tds.cs Проект: psni/mono
		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);
		}
Пример #15
0
Файл: Tds.cs Проект: psni/mono
		internal bool IsBlobType (TdsColumnType columnType)
		{
			return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText || columnType == TdsColumnType.Variant);
		}
Пример #16
0
Файл: Tds.cs Проект: psni/mono
		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;
			}
		}
Пример #17
0
Файл: Tds.cs Проект: psni/mono
		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;
			}
		}
Пример #18
0
Файл: Tds.cs Проект: psni/mono
		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;
			}
		}
Пример #19
0
Файл: Tds.cs Проект: psni/mono
		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;
		}
Пример #20
0
		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;
			}
		}
Пример #21
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;
		}
Пример #22
0
Файл: Tds.cs Проект: psni/mono
		internal bool IsLargeType (TdsColumnType columnType)
		{
			return ((byte) columnType > 128);
		}
Пример #23
0
        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;
        }
Пример #24
0
Файл: Tds.cs Проект: psni/mono
		protected bool IsWideType (TdsColumnType columnType)
		{
			switch (columnType) {
			case TdsColumnType.NChar:
			case TdsColumnType.NText:
			case TdsColumnType.NVarChar:
				return true;
			default:
				return false;
			}
		}
Пример #25
0
                private bool IsLargeType (TdsColumnType columnType)
		{
			return (columnType == TdsColumnType.NChar || (byte) columnType > 128);
		}
Пример #26
0
        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
        }
Пример #27
0
        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;
            }
        }
Пример #28
0
        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;
            }
        }
Пример #29
0
		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));
		}
Пример #30
0
		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;
		}
Пример #31
0
Файл: Tds.cs Проект: psni/mono
		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;
			}
		}
Пример #32
0
		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);
		}
Пример #33
0
        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());
        }
Пример #34
0
Файл: Tds.cs Проект: psni/mono
		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);
		}
Пример #36
0
Файл: Tds.cs Проект: psni/mono
		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;
		}
Пример #37
0
		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;
			}
		}
Пример #38
0
Файл: Tds.cs Проект: psni/mono
		protected object GetColumnValue (
			TdsColumnType? colType,
			bool outParam)
		{
			return GetColumnValue (colType, outParam, -1);
		}
Пример #39
0
		private void BeginLoad (
#if NET_2_0
			TdsColumnType? colType
Пример #40
0
        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));
        }
Пример #41
0
Файл: Tds.cs Проект: psni/mono
		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;
		}
Пример #42
0
		private object GetColumnValue (TdsColumnType colType, bool outParam)
		{
			return GetColumnValue (colType, outParam, -1);
		}
Пример #43
0
        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;
        }
Пример #44
0
        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);
            }
        }