Beispiel #1
0
        public static Encoding GetEncodingFromCollation(this TdsPackageReader reader)
        {
            var collation = reader.ReadCollation();
            var codePage  = collation.GetCodePage();

            return(reader.CurrentSession.GetEncodingFromCache(codePage));
        }
Beispiel #2
0
        public static int GetTokenLength(this TdsPackageReader reader, byte token)
        {
            switch (token & TdsEnums.SQLLenMask)
            {
            case TdsEnums.SQLZeroLen:
                return(0);

            case TdsEnums.SQLFixedLen:
                return(0x01 << ((token & 0x0c) >> 2));

            default:
                switch (token)
                {
                case TdsEnums.SQLFEATUREEXTACK:
                    return(-1);

                case TdsEnums.SQLSESSIONSTATE:
                    return(reader.ReadInt32());

                    ;

                case TdsEnums.SQLRETURNVALUE:
                    return(-1);        // In Yukon, the RETURNVALUE token stream no longer has length

                default:
                    return(reader.ReadUInt16());
                }
            }
        }
        private void SetupColMetaData(TdsPackageReader reader, TdsPackageWriter writer, int tdsType, byte precision, byte scale, bool isPlp)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            var r         = reader.CurrentResultSet.ColumnsMetadata = new ColumnsMetadata(1);
            var w         = writer.ColumnsMetadata = new MetadataBulkCopy[1];
            var collation = new SqlCollations {
                Info = 0x00d00409, SortId = 0x34
            };
            var encoding = Encoding.GetEncoding(collation.GetCodePage());

            w[0]         = new MetadataBulkCopy();
            r[0].TdsType = (byte)tdsType;
            w[0].TdsType = (byte)tdsType;
            r[0].Scale   = scale;
            w[0].Scale   = scale;
            r[0].IsPlp   = isPlp;
            w[0].IsPlp   = isPlp;
            r[0].IsPlp   = isPlp;
            w[0].Length  = scale;// nullable date testfix

            r[0].Encoding  = encoding;
            w[0].Encoding  = encoding;
            w[0].Collation = collation;

            w[0].Precision = precision;

            w[0].MetaType = TdsMetaType.TdsTypes[tdsType];
            r[0].MetaType = TdsMetaType.TdsTypes[tdsType];

            r[0].IsTextOrImage = r[0].MetaType.IsTextOrImage;
            w[0].IsTextOrImage = r[0].MetaType.IsTextOrImage;
        }
Beispiel #4
0
        public static MultiPartTableName?ReadMultiPartTableName(this TdsPackageReader reader)
        {
            // Find out how many parts in the TDS stream
            var nParts = reader.ReadByte();

            if (nParts == 0)
            {
                return(null);
            }

            var mpt = new MultiPartTableName();

            if (nParts == 4)
            {
                mpt.ServerName = reader.ReadString(reader.ReadUInt16());
            }

            if (nParts >= 3)
            {
                mpt.CatalogName = reader.ReadString(reader.ReadUInt16());
            }

            if (nParts >= 2)
            {
                mpt.SchemaName = reader.ReadString(reader.ReadUInt16());
            }

            mpt.TableName = reader.ReadString(reader.ReadUInt16());

            return(mpt);
        }
Beispiel #5
0
        public static EncryptionOptions ParseConnect(this TdsPackageReader reader, EncryptionOptions encryptionRequested)
        {
            var result = ParsePreLoginHandshake(reader.ReadBuffer, TdsEnums.HEADER_LEN, encryptionRequested);

            reader.PackageDone();
            return(result);
        }
Beispiel #6
0
        public static void SaveNbcBitmap(this TdsPackageReader reader)
        {
            var bitmap = reader.CurrentRow.NbcBitmap;

            reader.GetBytes(bitmap, bitmap.Length);
            reader.CurrentRow.IsNbcRow = true;
        }
Beispiel #7
0
 internal static Udt ReadUdtMetadata(this TdsPackageReader reader) =>
 new Udt
 {
     DatabaseName          = reader.ReadString(reader.ReadByte()),
     SchemaName            = reader.ReadString(reader.ReadByte()),
     TypeName              = reader.ReadString(reader.ReadByte()),
     AssemblyQualifiedName = reader.ReadString(reader.ReadUInt16())
 };
Beispiel #8
0
 public static int ReadTdsTypeLen(this TdsPackageReader reader, int len) =>
 len == 0
         ? 0
         : len == 1
             ? reader.ReadByte()
             : len == 2
                 ? reader.ReadUInt16()
                 : reader.ReadInt32();
Beispiel #9
0
        private static void ReadMetadata(TdsPackageReader reader, ColumnMetadata col)
        {
            // read user type - 4 bytes Yukon, 2 backwards
            reader.ReadUInt32();

            // read the 2 flags and set appropriate flags in structure
            col.Flag1 = reader.ReadByte();
            col.Flag2 = reader.ReadByte();

            var tdsType = col.TdsType = reader.ReadByte();

            var tmp = col.MetaType = TdsMetaType.TdsTypes[tdsType];

            col.IsPlp         = tmp.IsPlp;
            col.IsTextOrImage = tmp.IsTextOrImage;


            var length = ReadTdsTypeLen(reader, tmp.LenBytes);

            if (length == TdsEnums.SQL_USHORTVARMAXLEN && tmp.LenBytes == 2)
            {
                col.IsPlp = true;
            }

            if (tdsType == TdsEnums.SQLUDT)
            {
                reader.ReadUdtMetadata();
            }

            if (tdsType == TdsEnums.SQLXMLTYPE)
            {
                ReadXmlSchema(reader);
            }

            if (tmp.HasPrecision)
            {
                reader.ReadByte();
            }

            if (tmp.HasScale)
            {
                col.Scale = reader.ReadByte();
            }

            if (tmp.HasCollation)
            {
                col.Encoding = GetEncodingFromCollation(reader);
            }

            if (col.TdsType == TdsEnums.SQLTEXT || col.TdsType == TdsEnums.SQLNTEXT || col.TdsType == TdsEnums.SQLIMAGE)
            {
                ReadMultiPartTableName(reader);
            }

            col.Column = reader.ReadString(reader.ReadByte());
        }
Beispiel #10
0
        public static void ColMetaData(this TdsPackageReader reader, int columns)
        {
            reader.InitNbcBitmap(columns);

            var newMetaData = new ColumnsMetadata(columns);

            for (var i = 0; i < columns; i++)
            {
                ReadMetadata(reader, newMetaData[i]);
            }
            reader.CurrentResultSet.ColumnsMetadata = newMetaData;
        }
        public static MetadataBulkCopy[] ColMetaDataBulkCopy(this TdsPackageReader reader, int columns)
        {
            reader.InitNbcBitmap(columns);

            var newMetaData = new MetadataBulkCopy[columns];

            for (var i = 0; i < columns; i++)
            {
                newMetaData[i] = ReadMetadata(reader);
            }
            return(newMetaData);
        }
Beispiel #12
0
        public static void InitNbcBitmap(this TdsPackageReader reader, int columnsCount)
        {
            // 1-8 columns need 1 byte
            // 9-16: 2 bytes, and so on
            var bitmapArrayLength = (columnsCount + 7) / 8;
            var row = reader.CurrentRow;

            // allow reuse of previously allocated bitmap
            if (row.NbcBitmap?.Length != bitmapArrayLength)
            {
                row.NbcBitmap = new byte[bitmapArrayLength];
            }
        }
Beispiel #13
0
        public static SqlServerInfo LoginAck(this TdsPackageReader reader)
        {
            var sqlServerInfo = new SqlServerInfo();

            // read past interface type and version
            reader.ReadByte();

            var b          = reader.GetBytes(TdsEnums.VERSION_SIZE);
            var tdsVersion = (uint)((((((b[0] << 8) | b[1]) << 8) | b[2]) << 8) | b[3]); // bytes are in motorola order (high byte first)
            var majorMinor = tdsVersion & 0xff00ffff;
            var increment  = (tdsVersion >> 16) & 0xff;

            // Server responds:
            // 0x07000000 -> Sphinx         // Notice server response format is different for bwd compat
            // 0x07010000 -> Shiloh RTM     // Notice server response format is different for bwd compat
            // 0x71000001 -> Shiloh SP1
            // 0x72090002 -> Yukon RTM
            // 0x730B0003 -> Katmai RTM
            // 0x74000004 -> DENALI RTM
            // information provided by S. Ashwin

            switch (majorMinor)
            {
            case (TdsEnums.YUKON_MAJOR << 24) | TdsEnums.YUKON_RTM_MINOR when increment == TdsEnums.YUKON_INCREMENT:
                sqlServerInfo.IsYukon = true;
                break;

            case (TdsEnums.KATMAI_MAJOR << 24) | TdsEnums.KATMAI_MINOR when increment == TdsEnums.KATMAI_INCREMENT:
                sqlServerInfo.IsYukon         = true;
                sqlServerInfo.IsKatmaiOrNewer = true;
                break;

            case (TdsEnums.DENALI_MAJOR << 24) | TdsEnums.DENALI_MINOR when increment == TdsEnums.DENALI_INCREMENT:
                sqlServerInfo.IsYukon         = true;
                sqlServerInfo.IsKatmaiOrNewer = true;
                sqlServerInfo.IsDenali        = true;
                break;

            default:
                throw SQL.InvalidTdsVersion();
            }
            //isYukon is always true otherwise we send an exception

            var len = reader.ReadByte();

            sqlServerInfo.Name         = reader.ReadUnicodeChars(len * 2);
            sqlServerInfo.MajorVersion = reader.ReadByte();
            sqlServerInfo.MinorVersion = reader.ReadByte();
            sqlServerInfo.BuildNum     = (short)((reader.ReadByte() << 8) + reader.ReadByte());
            return(sqlServerInfo);
        }
Beispiel #14
0
        internal static long EnvSqlTransaction(this TdsPackageReader reader)
        {
            var newTransactionId = 0L;

            if (reader.ReadByte() == 8)
            {
                newTransactionId = reader.ReadInt64();
            }
            if (reader.ReadByte() == 8)
            {
                reader.ReadInt64();
            }
            return(newTransactionId);
        }
Beispiel #15
0
        public void get_npSniHandle()
        {
            const bool marsOn = false;
            var        p      = new ServerConnectionOptions(@"(localdb)\mssqllocaldb", false);
            var        handle = new TdsStreamNamedPipes(p.PipeServerName, p.PipeName, 15);
            var        writer = new TdsPackageWriter(handle);
            var        reader = new TdsPackageReader(handle);

            writer.SendPreLoginHandshake("", marsOn);
            reader.CheckBuffer(8);
            var result = ParserPreLogin.ParsePreLoginHandshake(reader.ReadBuffer, TdsEnums.HEADER_LEN, EncryptionOptions.OFF);

            Assert.Equal(EncryptionOptions.OFF, result);
        }
Beispiel #16
0
        public static XmlSchema?ReadXmlSchema(this TdsPackageReader reader)
        {
            var schemaPresent = reader.ReadByte();

            if ((schemaPresent & 1) != 0)
            {
                return new XmlSchema
                       {
                           CollectionDatabase     = reader.ReadString(reader.ReadByte()),
                           CollectionOwningSchema = reader.ReadString(reader.ReadByte()),
                           CollectionName         = reader.ReadString(reader.ReadUInt16())
                       }
            }
            ;
            return(null);
        }
Beispiel #17
0
        public static Func <TdsColumnReader, T> GetComplexReader <T>(TdsPackageReader reader)
        {
            var sqlTableColumns  = GetDefaultMapping(reader.CurrentResultSet.ColumnsMetadata);
            var typeColumns      = typeof(T).GetPublicProperties();
            var columnsNotMapped = sqlTableColumns.Select(x => x.SqlName).Except(typeColumns.Keys).ToArray();

            if (columnsNotMapped.Any())
            {
                throw new ArgumentException($"Not all columns are mapped to class properties. The follow columns could not mapped: {string.Join(",", columnsNotMapped)}");
            }

            var newMapping = sqlTableColumns.Select(x => new Mapping {
                SqlIndex = x.SqlIndex, ClrType = typeColumns[x.SqlName].PropertyType, TdsType = x.TdsType, PropertyName = x.SqlName
            }).ToArray();

            return(_GetReader <T>(newMapping));
        }
        // read feature ID
        public static void FeatureExtAck(this TdsPackageReader reader)
        {
            while (true)
            {
                var featureId = reader.ReadByte();

                if (featureId == TdsEnums.FEATUREEXT_TERMINATOR)
                {
                    break;
                }
                var dataLen = reader.ReadUInt32();
                var data    = reader.GetBytes(checked ((int)dataLen));
                if (dataLen > 0)
                {
                    OnFeatureExtAck(featureId, data);
                }
            }
        }
Beispiel #19
0
        internal static void EnvCollation(this TdsPackageReader reader)
        {
            var newLength = reader.ReadByte();

            if (newLength == 5)
            {
                var collation = reader.ReadCollation();
                var codepage  = collation.GetCodePage();
                reader.CurrentSession.DefaultCollation = collation;
                reader.CurrentSession.DefaultEncoding  = reader.CurrentSession.GetEncodingFromCache(codepage);
            }

            var oldLength = reader.ReadByte();

            if (oldLength == 5)
            {
                var oldCollation = reader.ReadCollation();
            }
        }
Beispiel #20
0
        internal static void EnvCharset(this TdsPackageReader reader)
        {
            var newValue = reader.ReadString(reader.ReadByte());
            var oldValue = reader.ReadString(reader.ReadByte());

            // we copied this behavior directly from luxor - see charset envchange
            // section from sqlctokn.c
            if (newValue == TdsEnums.DEFAULT_ENGLISH_CODE_PAGE_STRING)
            {
                reader.CurrentSession.DefaultCodePage = TdsEnums.DEFAULT_ENGLISH_CODE_PAGE_VALUE;
                reader.CurrentSession.DefaultEncoding = Encoding.GetEncoding(reader.CurrentSession.DefaultCodePage);
                return;
            }

            var stringCodePage = newValue.Substring(TdsEnums.CHARSET_CODE_PAGE_OFFSET);

            reader.CurrentSession.DefaultCodePage = int.Parse(stringCodePage, NumberStyles.Integer, CultureInfo.InvariantCulture);
            reader.CurrentSession.DefaultEncoding = Encoding.GetEncoding(reader.CurrentSession.DefaultCodePage);
        }
Beispiel #21
0
        public static void SqlErrorAndInfo(this TdsPackageReader reader, byte token, int tokenLength)
        {
            var start = reader.GetReadPos();
            var error = new SqlInfoAndError
            {
                Number    = reader.ReadInt32(),
                State     = reader.ReadByte(),
                Class     = reader.ReadByte(),
                Message   = reader.ReadString(reader.ReadUInt16()),
                Server    = reader.ReadString(reader.ReadByte()),
                Procedure = reader.ReadString(reader.ReadByte())
            };
            var current = reader.GetReadPos();

            error.LineNumber = tokenLength - (current - start) > 2 ? reader.ReadInt32() : reader.ReadInt16();
            if (error.Class >= TdsEnums.MIN_ERROR_CLASS)
            {
                throw new Exception(error.Message);
            }
            reader.CurrentSession.Errors.Add(error);
        }
Beispiel #22
0
 public static void EnvPackageSize(this TdsPackageReader tdsPackageReader)
 {
     var newValue   = tdsPackageReader.ReadString(tdsPackageReader.ReadByte());
     var oldValue   = tdsPackageReader.ReadString(tdsPackageReader.ReadByte());
     var packetSize = int.Parse(newValue, NumberStyles.Integer, CultureInfo.InvariantCulture);
 }
Beispiel #23
0
        public static bool SqlDone(this TdsPackageReader reader)
        {
            // status
            // command
            // rowcount (valid only if DONE_COUNT bit is set)
            bool attentionReceived;
            var  status = reader.ReadUInt16();
            var  curCmd = reader.ReadUInt16();
            var  count  = (int)reader.ReadInt64();


            // We get a done token with the attention bit set
            if (TdsEnums.DONE_ATTN == (status & TdsEnums.DONE_ATTN))
            {
                attentionReceived = true;
            }

            //if (cmd != null && TdsEnums.DONE_COUNT == (status & TdsEnums.DONE_COUNT))
            //{
            //    if (curCmd != TdsEnums.SELECT) cmd.InternalRecordsAffected = count;
            //    // Skip the bogus DONE counts sent by the server
            //    if (curCmd != TdsEnums.SELECT) cmd.OnStatementCompleted(count);
            //}


            // Surface exception for DONE_ERROR in the case we did not receive an error token
            // in the stream, but an error occurred.  In these cases, we throw a general server error.  The
            // situations where this can occur are: an invalid buffer received from client, login error
            // and the server refused our connection, and the case where we are trying to log in but
            // the server has reached its max connection limit.  Bottom line, we need to throw general
            // error in the cases where we did not receive an error token along with the DONE_ERROR.
            if (TdsEnums.DONE_ERROR == (TdsEnums.DONE_ERROR & status))
            {
            }

            // Similar to above, only with a more severe error.  In this case, if we received
            // the done_srverror, this exception will be added to the collection regardless.
            // The server will always break the connection in this case.
            if (TdsEnums.DONE_SRVERROR == (TdsEnums.DONE_SRVERROR & status))
            {
            }


            // stop if the DONE_MORE bit isn't set (see above for attention handling)
            var _pendingData   = false;
            var _hasOpenResult = false;

            if (TdsEnums.DONE_MORE != (status & TdsEnums.DONE_MORE))
            {
                return(true);
            }

            // _pendingData set by e.g. 'TdsExecuteSQLBatch'
            // _hasOpenResult always set to true by 'WriteMarsHeader'
            //
            if (!_pendingData && _hasOpenResult)
            {
                ;
            }
            return(false);
        }
        private static MetadataBulkCopy ReadMetadata(TdsPackageReader reader)
        {
            var col = new MetadataBulkCopy();

            // read user type - 4 bytes Yukon, 2 backwards
            reader.ReadUInt32();

            // read the 2 flags and set appropriate flags in structure
            col.Flag1 = reader.ReadByte();
            col.Flag2 = reader.ReadByte();

            var tdsType = reader.ReadByte();

            col.TdsType = tdsType;

            var tmp = col.MetaType = TdsMetaType.TdsTypes[tdsType];

            col.IsPlp         = tmp.IsPlp;
            col.IsTextOrImage = tmp.IsTextOrImage;

            var length = col.Length = reader.ReadTdsTypeLen(tmp.LenBytes);

            if (length == TdsEnums.SQL_USHORTVARMAXLEN && tmp.LenBytes == 2)
            {
                col.IsPlp = true;
            }

            if (tdsType == TdsEnums.SQLUDT)
            {
                reader.ReadUdtMetadata();
            }

            if (tdsType == TdsEnums.SQLXMLTYPE)
            {
                reader.ReadXmlSchema();
            }

            if (tmp.HasPrecision)
            {
                col.Precision = reader.ReadByte();
            }

            if (tmp.HasScale)
            {
                col.Scale = reader.ReadByte();
            }

            if (tmp.HasCollation)
            {
                col.Collation = reader.ReadCollation();
                col.Encoding  = reader.CurrentSession.GetEncodingFromCache(col.Collation.GetCodePage());
            }

            if (col.IsTextOrImage)
            {
                col.PartTableName = reader.ReadMultiPartTableName();
            }

            //bulkcopy typeCorrection
            if (tdsType == TdsEnums.SQLXMLTYPE)
            {
                col.TdsType   = TdsEnums.SQLNVARCHAR;
                col.Length    = TdsEnums.SQL_USHORTVARMAXLEN;
                col.Collation = new SqlCollations();
            }

            if (tdsType == TdsEnums.SQLUDT)
            {
                col.TdsType = TdsEnums.SQLBIGVARBINARY;
                col.Length  = TdsEnums.SQL_USHORTVARMAXLEN;
            }

            col.Column = reader.ReadString(reader.ReadByte());
            return(col);
        }
        private void TestIntN(object value, int tdsType, bool nulltest, byte precision = 0, byte scale = 0, bool isPlp = false)
        {
            var stream = new TestStream();
            var writer = new TdsPackageWriter(stream);
            var reader = new TdsPackageReader(stream);

            SetupColMetaData(reader, writer, tdsType, precision, scale, isPlp);
            var columwriter  = new TdsColumnWriter(writer);
            var columnReader = new TdsColumnReader(reader);

            object result;

            if (nulltest)
            {
                writer.NewPackage(TdsEnums.MT_RPC);
                ObjectWriter(columwriter, tdsType, value, nulltest);
                writer.SendLastMessage();
                result = ObjectReader(columnReader, value);
                Assert.Null(result);
            }

            writer.NewPackage(TdsEnums.MT_RPC);
            ObjectWriter(columwriter, tdsType, value, false);
            writer.SendLastMessage();
            result = ObjectReader(columnReader, value);
            switch (value)
            {
            case Money v:
                Assert.Equal((decimal)v, result);
                break;

            case Money4 v:
                Assert.Equal((decimal)v, result);
                break;

            case SqlDate v:
                Assert.Equal((DateTime)v, result);
                break;

            case SqlDateTime2 v:
                Assert.Equal((DateTime)v, result);
                break;

            case SqlDateTime4 v:
                Assert.Equal((DateTime)v, result);
                break;

            case SqlImage v:
                Assert.Equal((byte[])v, result);
                break;

            case SqlUnicode v:
                Assert.Equal((string)v, result);
                break;

            case SqlXml v:
                Assert.Equal((string)v, result);
                break;

            case SqlVariant v:
                switch (v.Value)
                {
                case bool b: Assert.Equal(b, result); break;

                case byte b: Assert.Equal(b, result); break;

                case short b: Assert.Equal(b, result); break;

                case int b: Assert.Equal(b, result); break;

                case long b: Assert.Equal(b, result); break;

                case float b: Assert.Equal(b, result); break;

                case double b: Assert.Equal(b, result); break;

                case DateTime b: Assert.Equal(b, result); break;

                case Guid b: Assert.Equal(b, result); break;

                case decimal b: Assert.Equal(b, result); break;

                case byte[] b: Assert.Equal(b, result); break;

                case string b: Assert.Equal(b, result); break;

                case TimeSpan b: Assert.Equal(b, result); break;

                case DateTimeOffset b: Assert.Equal(b, result); break;

                default:
                    Assert.False(true);
                    break;
                }

                break;

            default:
                Assert.Equal(value, result);
                break;
            }

            Assert.Equal(reader.GetReadEndPos(), reader.GetReadPos());
            if (!new[]
            {
                TdsEnums.SQLBIGBINARY,
                TdsEnums.SQLBIGVARBINARY,
                TdsEnums.SQLBIGVARCHAR,
                TdsEnums.SQLBIGCHAR,
                TdsEnums.SQLTEXT,
                TdsEnums.SQLNVARCHAR,
                TdsEnums.SQLNTEXT,
                TdsEnums.SQLNCHAR,
                TdsEnums.SQLXMLTYPE,
                TdsEnums.SQLIMAGE,
            }.Contains(tdsType) && !(value is SqlVariant v1 && (v1.Value is string s || v1.Value is byte[])))
            {
                Assert.InRange(reader.GetReadPos() - 8, 0, TdsEnums.MaxSizeSqlValue);
            }
        }
Beispiel #26
0
 public TdsPackage(ITdsStream tdsStream)
 {
     Reader = new TdsPackageReader(tdsStream);
     Writer = new TdsPackageWriter(tdsStream);
 }
Beispiel #27
0
 public TdsColumnReader(TdsPackageReader reader)
 {
     _reader  = reader;
     MetaData = reader.CurrentResultSet.ColumnsMetadata;
 }
        public static void ParseSessionState(this TdsPackageReader reader, int length)
        {
            var sdata = reader.CurrentSession.CurrentSessionData;

            if (length < 5)
            {
                throw SQL.ParsingError();
            }
            var seqNum = reader.ReadUInt32();

            if (seqNum == uint.MaxValue)
            {
                reader.CurrentSession.DoNotPoolThisConnection = true;
            }
            var status = reader.ReadByte();

            if (status > 1)
            {
                throw SQL.ParsingError();
            }
            var recoverable = status != 0;

            length -= 5;

            while (length > 0)
            {
                var stateId      = reader.ReadByte();
                var stateLenByte = reader.ReadByte();
                var stateLen     = stateLenByte < 0xFF
                    ? stateLenByte
                    : reader.ReadInt32();

                byte[] buffer = null;
                lock (sdata.Delta)
                {
                    if (sdata.Delta[stateId] == null)
                    {
                        buffer = new byte[stateLen];
                        sdata.Delta[stateId] = new SessionStateRecord {
                            Version = seqNum, DataLength = stateLen, Data = buffer, Recoverable = recoverable
                        };
                        sdata.DeltaDirty = true;
                        if (!recoverable)
                        {
                            checked
                            {
                                sdata.UnrecoverableStatesCount++;
                            }
                        }
                    }
                    else
                    {
                        if (sdata.Delta[stateId].Version <= seqNum)
                        {
                            var sv = sdata.Delta[stateId];
                            sv.Version    = seqNum;
                            sv.DataLength = stateLen;
                            if (sv.Recoverable != recoverable)
                            {
                                if (recoverable)
                                {
                                    Debug.Assert(sdata.UnrecoverableStatesCount > 0, "Unrecoverable states count >0");
                                    sdata.UnrecoverableStatesCount--;
                                }
                                else
                                {
                                    checked
                                    {
                                        sdata.UnrecoverableStatesCount++;
                                    }
                                }

                                sv.Recoverable = recoverable;
                            }

                            buffer = sv.Data;
                            if (buffer.Length < stateLen)
                            {
                                buffer  = new byte[stateLen];
                                sv.Data = buffer;
                            }
                        }
                    }
                }

                if (buffer != null)
                {
                    reader.ReadByteArray(buffer, 0, stateLen);
                }
                else
                {
                    reader.GetBytes(stateLen);
                }

                length -= stateLenByte < 0xFF
                    ? 2 + stateLen
                    : 6 + stateLen;
            }
        }
Beispiel #29
0
        public static void EnvChange(this TdsPackageReader reader, int tokenLength, Action <int> transactionAction)
        {
            // There could be multiple environment change messages following this token.
            var processedLength = 0;

            var startpos = reader.GetReadPos();

            while (tokenLength > processedLength)
            {
                var type = reader.ReadByte();
                switch (type)
                {
                case TdsEnums.ENV_DATABASE:
                case TdsEnums.ENV_LANG:
                    reader.EnvLanguage();
                    break;

                case TdsEnums.ENV_CHARSET:
                    reader.EnvCharset();
                    break;

                case TdsEnums.ENV_PACKETSIZE:
                    reader.EnvPackageSize();
                    break;

                case TdsEnums.ENV_LOCALEID:
                    throw new NotImplementedException();

                case TdsEnums.ENV_COMPFLAGS:
                    throw new NotImplementedException();

                case TdsEnums.ENV_COLLATION:
                    reader.EnvCollation();
                    break;

                case TdsEnums.ENV_BEGINTRAN:
                case TdsEnums.ENV_COMMITTRAN:
                case TdsEnums.ENV_ROLLBACKTRAN:
                case TdsEnums.ENV_ENLISTDTC:
                case TdsEnums.ENV_DEFECTDTC:
                case TdsEnums.ENV_TRANSACTIONENDED:
                    if (transactionAction == null)
                    {
                        reader.EnvSqlTransaction();
                    }
                    else
                    {
                        transactionAction(type);
                    }
                    break;

                case TdsEnums.ENV_LOGSHIPNODE:
                    throw new NotImplementedException();

                case TdsEnums.ENV_PROMOTETRANSACTION:
                    throw new NotImplementedException();

                case TdsEnums.ENV_TRANSACTIONMANAGERADDRESS:
                case TdsEnums.ENV_SPRESETCONNECTIONACK:
                    throw new NotImplementedException();

                case TdsEnums.ENV_USERINSTANCE:
                    throw new NotImplementedException();

                case TdsEnums.ENV_ROUTING:
                    throw new NotImplementedException();

                default:
                    Debug.Assert(false, "Unknown environment change token: " + type);
                    break;
                }

                processedLength = reader.GetReadPos() - startpos;
            }
        }
Beispiel #30
0
 private static Func <TdsColumnReader, T> GetRowReader <T>(TdsPackageReader reader, string key) where T : class, new()
 {
     return((Func <TdsColumnReader, T>)Readers.GetOrAdd(key, x => RowReader.GetComplexReader <T>(reader)));
 }