상속: System.IO.Stream
        public void SqlStream_ExecuteNonQuery_Enumerates_Entire_Stream()
        {
            int actual = 0;
            int expected = 100;

            var connection = new Mock<ISqlStreamConnection>();
            connection.Setup(c => c.ExecuteNonQuery(It.IsAny<SqlCommand>())).Callback<SqlCommand>((cmd) =>
                {
                    var stream = cmd.Parameters["@stream"].Value as SqlStructuredParameterWrapper<StreamSchema>;
                    Assert.IsNotNull(stream, "@stream parameter cannot be null.");

                    foreach (var item in stream)
                        actual++;
                });

            using (SqlStream<StreamSchema> target = new SqlStream<StreamSchema>(connection.Object, SqlStreamBehavior.CloseConnection, 10))
            {
                target.Parameters.Add("@userid", SqlDbType.Int).Value = 1;
                target.Parameters.AddStructured<StreamSchema>("@stream", "dbo.StreamUDT", target)
                    .Map(src => src.Id, "Id", SqlDbType.Int)
                    .Map(src => src.ProductName, "ProductName", SqlDbType.VarChar, 255)
                    .Map(src => Convert.ToDecimal(src.Price), "Price", SqlDbType.Decimal, 9, 3);

                for (int i = 0; i < expected; i++)
                {
                    target.Write(new StreamSchema
                    {
                        Id = i,
                        ProductName = String.Format("Product {0}", i),
                        Price = (i + 1.0) - 0.01
                    });

                    //simulate I/O
                    Thread.Sleep(3);
                }
            }

            Assert.AreEqual(expected, actual, "Data wasn't streamed.");
        }
예제 #2
0
        public long GetChars(long dataIndex, char[] buffer, int bufferIndex, int length)
        {
            if (_xmlReader == null)
            {
                SqlStream sqlStream = new SqlStream(_columnOrdinal, _reader, true /* addByteOrderMark */, false /* processAllRows*/, false /*advanceReader*/);
                _xmlReader = sqlStream.ToXmlReader();
                _strWriter = new StringWriter((System.IFormatProvider)null);
                XmlWriterSettings writerSettings = new XmlWriterSettings();
                writerSettings.CloseOutput = true;      // close the memory stream when done
                writerSettings.ConformanceLevel = ConformanceLevel.Fragment;
                _xmlWriter = XmlWriter.Create(_strWriter, writerSettings);
            }

            int charsToSkip = 0;
            int cnt = 0;
            if (dataIndex < _charsRemoved)
            {
                throw ADP.NonSeqByteAccess(dataIndex, _charsRemoved, ADP.GetChars);
            }
            else if (dataIndex > _charsRemoved)
            {
                charsToSkip = (int)(dataIndex - _charsRemoved);
            }

            // If buffer parameter is null, we have to return -1 since there is no way for us to know the
            // total size up front without reading and converting the XML.
            if (buffer == null)
            {
                return (long)(-1);
            }

            StringBuilder strBldr = _strWriter.GetStringBuilder();
            while (!_xmlReader.EOF)
            {
                if (strBldr.Length >= (length + charsToSkip))
                {
                    break;
                }
                // Can't call _xmlWriter.WriteNode here, since it reads all of the data in before returning the first char.
                // Do own implementation of WriteNode instead that reads just enough data to return the required number of chars
                //_xmlWriter.WriteNode(_xmlReader, true);
                //  _xmlWriter.Flush();
                WriteXmlElement();
                if (charsToSkip > 0)
                {
                    // Aggressively remove the characters we want to skip to avoid growing StringBuilder size too much
                    cnt = strBldr.Length < charsToSkip ? strBldr.Length : charsToSkip;
                    strBldr.Remove(0, cnt);
                    charsToSkip -= cnt;
                    _charsRemoved += (long)cnt;
                }
            }

            if (charsToSkip > 0)
            {
                cnt = strBldr.Length < charsToSkip ? strBldr.Length : charsToSkip;
                strBldr.Remove(0, cnt);
                charsToSkip -= cnt;
                _charsRemoved += (long)cnt;
            }

            if (strBldr.Length == 0)
            {
                return 0;
            }
            // At this point charsToSkip must be 0
            Debug.Assert(charsToSkip == 0);

            cnt = strBldr.Length < length ? strBldr.Length : length;
            for (int i = 0; i < cnt; i++)
            {
                buffer[bufferIndex + i] = strBldr[i];
            }
            // Remove the characters we have already returned
            strBldr.Remove(0, cnt);
            _charsRemoved += (long)cnt;
            return (long)cnt;
        }
 private XmlReader CompleteXmlReader(SqlDataReader ds)
 {
     XmlReader reader = null;
     SmiExtendedMetaData[] internalSmiMetaData = ds.GetInternalSmiMetaData();
     if (((internalSmiMetaData != null) && (internalSmiMetaData.Length == 1)) && (((internalSmiMetaData[0].SqlDbType == SqlDbType.NText) || (internalSmiMetaData[0].SqlDbType == SqlDbType.NVarChar)) || (internalSmiMetaData[0].SqlDbType == SqlDbType.Xml)))
     {
         try
         {
             reader = new SqlStream(ds, true, internalSmiMetaData[0].SqlDbType != SqlDbType.Xml).ToXmlReader();
         }
         catch (Exception exception)
         {
             if (ADP.IsCatchableExceptionType(exception))
             {
                 ds.Close();
             }
             throw;
         }
     }
     if (reader == null)
     {
         ds.Close();
         throw SQL.NonXmlResult();
     }
     return reader;
 }
예제 #4
0
        public long GetChars(long dataIndex, char[] buffer, int bufferIndex, int length)
        {
            if (_xmlReader == null)
            {
                SqlStream sqlStream = new SqlStream(_columnOrdinal, _reader, true /* addByteOrderMark */, false /* processAllRows*/, false /*advanceReader*/);
                _xmlReader = sqlStream.ToXmlReader();
                _strWriter = new StringWriter((System.IFormatProvider)null);
                XmlWriterSettings writerSettings = new XmlWriterSettings();
                writerSettings.CloseOutput      = true; // close the memory stream when done
                writerSettings.ConformanceLevel = ConformanceLevel.Fragment;
                _xmlWriter = XmlWriter.Create(_strWriter, writerSettings);
            }

            int charsToSkip = 0;
            int cnt         = 0;

            if (dataIndex < _charsRemoved)
            {
                throw ADP.NonSeqByteAccess(dataIndex, _charsRemoved, nameof(GetChars));
            }
            else if (dataIndex > _charsRemoved)
            {
                charsToSkip = (int)(dataIndex - _charsRemoved);
            }

            // If buffer parameter is null, we have to return -1 since there is no way for us to know the
            // total size up front without reading and converting the XML.
            if (buffer == null)
            {
                return((long)(-1));
            }

            StringBuilder strBldr = _strWriter.GetStringBuilder();

            while (!_xmlReader.EOF)
            {
                if (strBldr.Length >= (length + charsToSkip))
                {
                    break;
                }
                // Can't call _xmlWriter.WriteNode here, since it reads all of the data in before returning the first char.
                // Do own implementation of WriteNode instead that reads just enough data to return the required number of chars
                //_xmlWriter.WriteNode(_xmlReader, true);
                //  _xmlWriter.Flush();
                WriteXmlElement();
                if (charsToSkip > 0)
                {
                    // Aggressively remove the characters we want to skip to avoid growing StringBuilder size too much
                    cnt = strBldr.Length < charsToSkip ? strBldr.Length : charsToSkip;
                    strBldr.Remove(0, cnt);
                    charsToSkip   -= cnt;
                    _charsRemoved += (long)cnt;
                }
            }

            if (charsToSkip > 0)
            {
                cnt = strBldr.Length < charsToSkip ? strBldr.Length : charsToSkip;
                strBldr.Remove(0, cnt);
                charsToSkip   -= cnt;
                _charsRemoved += (long)cnt;
            }

            if (strBldr.Length == 0)
            {
                return(0);
            }
            // At this point charsToSkip must be 0
            Debug.Assert(charsToSkip == 0);

            cnt = strBldr.Length < length ? strBldr.Length : length;
            for (int i = 0; i < cnt; i++)
            {
                buffer[bufferIndex + i] = strBldr[i];
            }
            // Remove the characters we have already returned
            strBldr.Remove(0, cnt);
            _charsRemoved += (long)cnt;
            return((long)cnt);
        }
        public void SqlStream_Integration_Test_With_Output_Parameter()
        {
            int actual = 0;
            int expected = 100;

            using (SqlStream<StreamSchema> target = new SqlStream<StreamSchema>(new SqlStreamConnection("Server=(local);Database=tempdb;Trusted_Connection=Yes;"), SqlStreamBehavior.CloseConnection, 10))
            {
                target.StoredProcedureName = "dbo.TVPTestProc";

                target.Parameters.AddStructured<StreamSchema>("@stream", "dbo.StreamSchema", target)
                    .Map(src => src.Id, "Id", SqlDbType.Int)
                    .Map(src => src.ProductName, "ProductName", SqlDbType.VarChar, 255)
                    .Map(src => Convert.ToDecimal(src.Price), "Price", SqlDbType.Decimal, 9, 3);

                target.Parameters.Add("@userid", SqlDbType.Int).Value = 1;
                var output = target.Parameters.Add("@resultCount", SqlDbType.Int);
                output.Direction = ParameterDirection.InputOutput;
                output.Value = 0;

                for (int i = 0; i < expected; i++)
                {
                    target.Write(new StreamSchema
                    {
                        Id = i,
                        ProductName = String.Format("Product {0}", i),
                        Price = (i + 1.0) - 0.01
                    });
                }

                // need to wait for Close() or Dispose() before checking output parameters
                target.Close();
                actual = Convert.ToInt32(output.Value);
            }

            Assert.AreEqual(expected, actual, "Data wasn't streamed.");
        }