public async Task AddTransactions(IEnumerable <ByteString> transactions)
        {
            using (SqlTransaction context = Connection.BeginTransaction(IsolationLevel.Snapshot))
            {
                foreach (ByteString rawTransaction in transactions)
                {
                    byte[]      rawTransactionBuffer = rawTransaction.ToByteArray();
                    Transaction transaction          = MessageSerializer.DeserializeTransaction(rawTransaction);
                    byte[]      transactionHash      = MessageSerializer.ComputeHash(rawTransactionBuffer);

                    byte[]   mutationHash = MessageSerializer.ComputeHash(transaction.Mutation.ToByteArray());
                    Mutation mutation     = MessageSerializer.DeserializeMutation(transaction.Mutation);

                    IReadOnlyList <Record> conflicts = await ExecuteQuery <Record>(
                        "EXEC [Openchain].[AddTransaction] @instance, @transactionHash, @mutationHash, @rawData, @records;",
                        reader => mutation.Records.First(record => record.Key.Equals(new ByteString((byte[])reader[0]))),
                        new Dictionary <string, object>()
                    {
                        ["instance"]        = this.instanceId,
                        ["transactionHash"] = transactionHash,
                        ["mutationHash"]    = mutationHash,
                        ["rawData"]         = rawTransactionBuffer,
                        ["type:records"]    = "Openchain.RecordMutationTable",
                        ["records"]         = mutation.Records.Select(record =>
                        {
                            SqlDataRecord result = new SqlDataRecord(recordMutationMetadata);

                            RecordKey key = ParseRecordKey(record.Key);
                            result.SetBytes(0, 0, record.Key.ToByteArray(), 0, record.Key.Value.Count);

                            if (record.Value == null)
                            {
                                result.SetDBNull(1);
                            }
                            else
                            {
                                result.SetBytes(1, 0, record.Value.ToByteArray(), 0, record.Value.Value.Count);
                            }

                            result.SetBytes(2, 0, record.Version.ToByteArray(), 0, record.Version.Value.Count);
                            result.SetString(3, key.Name);
                            result.SetByte(4, (byte)key.RecordType);
                            return(result);
                        }).ToList()
                    },
                        context);

                    if (conflicts.Count > 0)
                    {
                        throw new ConcurrentMutationException(conflicts[0]);
                    }
                }

                context.Commit();
            }
        }
        public async Task <IReadOnlyList <ByteString> > GetTransactionsByMutationHash(IEnumerable <ByteString> mutationHashes)
        {
            var hashList = new List <ByteString>(mutationHashes);

            if (hashList.Count == 0)
            {
                return(new ByteString[0]);
            }

            var records = await ExecuteQuery(
                "EXEC [Openchain].[GetTransactions] @instance, @mutationHashes;",
                reader => new ByteString((byte[])reader[0]),
                new Dictionary <string, object>()
            {
                ["instance"]            = this.instanceId,
                ["type:mutationHashes"] = "Openchain.IdTable",
                ["mutationHashes"]      = hashList.Select(key =>
                {
                    SqlDataRecord record = new SqlDataRecord(idMetadata);
                    record.SetBytes(0, 0, key.ToByteArray(), 0, key.Value.Count);
                    return(record);
                }).ToList()
            });

            return(records);
        }
        public async Task <IReadOnlyList <ByteString> > GetTransactionByRecordKeys(IEnumerable <ByteString> keys, TransactionFilter filter)
        {
            var keyList = new List <ByteString>(keys);

            if (keyList.Count == 0)
            {
                return(new ByteString[0]);
            }

            var records = await ExecuteQuery(
                "EXEC [Openchain].[GetTransactionByRecordKeys1] @instance, @ids, @start, @end;",
                reader => new ByteString((byte[])reader[0]),
                new Dictionary <string, object>()
            {
                ["instance"] = this.instanceId,
                ["type:ids"] = "Openchain.IdTable",
                ["ids"]      = keyList.Select(key =>
                {
                    SqlDataRecord record = new SqlDataRecord(idMetadata);
                    record.SetBytes(0, 0, key.ToByteArray(), 0, key.Value.Count);
                    return(record);
                }).ToList(),
                ["start"] = filter.StartDate,
                ["end"]   = filter.EndDate
            });

            return(records);
        }
Exemplo n.º 4
0
        public override void Set(SqlDataRecord record, int ordinal, Stream value)
        {
            if (value != null)
            {
                int    length = (int)value.Length;
                byte[] bytes  = ArrayPool <byte> .Shared.Rent(length);

                try
                {
                    using (var ms = new MemoryStream(bytes))
                    {
                        value.CopyTo(ms, length);
                    }

                    record.SetBytes(ordinal, 0, bytes, 0, length);
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(bytes);
                }
            }
            else
            {
                record.SetDBNull(ordinal);
            }
        }
 public static void SetNullableImage(this SqlDataRecord rec, int index, byte[] value)
 {
     if (value != null)
     {
         rec.SetBytes(index, 0, value, 0, value.Length);
     }
     else
     {
         rec.SetDBNull(index);
     }
 }
Exemplo n.º 6
0
 internal override void SetDataRecordValue(SqlDataRecord record, int ordinal)
 {
     if (InputValue == null)
     {
         record.SetDBNull(ordinal);
     }
     else
     {
         record.SetBytes(ordinal, 0, InputValue, 0, InputValue.Length);
     }
 }
Exemplo n.º 7
0
 public override void Set(SqlDataRecord record, int ordinal, byte[] value)
 {
     if (value != null)
     {
         record.SetBytes(ordinal, fieldOffset: 0, value, bufferOffset: 0, value.Length);
     }
     else
     {
         record.SetDBNull(ordinal);
     }
 }
        public override void Set(SqlDataRecord record, int ordinal, byte[] value)
        {
            EnsureArg.IsNotNull(record, nameof(record));

            if (value != null)
            {
                record.SetBytes(ordinal, fieldOffset: 0, value, bufferOffset: 0, value.Length);
            }
            else
            {
                record.SetDBNull(ordinal);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Extends SetBytes so that buffer offset of 0 and call to Array.Length are not needed.
        /// <example>
        /// sqldatarecord.SetBytes(ordinal, fieldOffset, buffer);
        /// </example>
        /// </summary>
        public static void SetBytes(this SqlDataRecord sqldatarecord, Int32 ordinal, Int64 fieldOffset, Byte[] buffer)
        {
            if (sqldatarecord == null)
            {
                throw new ArgumentNullException("sqldatarecord");
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            sqldatarecord.SetBytes(ordinal, fieldOffset, buffer, 0, buffer.Length);
        }
Exemplo n.º 10
0
 private static void SetRecordValueFromString(SqlDataRecord outputRecord, SqlMetaData[] columns, int columnID, string valueString)
 {
     if (valueString == null)
     {
         outputRecord.SetValue(columnID, null);
     }
     else
     {
         if (columns[columnID].DbType == DbType.Binary)
         {
             byte[] binaryData = Convert.FromBase64String(valueString);
             outputRecord.SetBytes(columnID, 0, binaryData, 0, binaryData.Length);
         }
         else
         {
             outputRecord.SetSqlString(columnID, new SqlString(valueString));
         }
     }
 }
        public async Task <IReadOnlyList <Record> > GetRecords(IEnumerable <ByteString> keys)
        {
            List <ByteString> keyList = new List <ByteString>(keys);

            if (keyList.Count == 0)
            {
                return(new Record[0]);
            }

            IReadOnlyList <Record> records = await ExecuteQuery <Record>(
                "EXEC [Openchain].[GetRecords] @instance, @ids;",
                reader => new Record(new ByteString((byte[])reader[0]), new ByteString((byte[])reader[1]), new ByteString((byte[])reader[2])),
                new Dictionary <string, object>()
            {
                ["instance"] = this.instanceId,
                ["type:ids"] = "Openchain.IdTable",
                ["ids"]      = keyList.Select(key =>
                {
                    SqlDataRecord record = new SqlDataRecord(idMetadata);
                    record.SetBytes(0, 0, key.ToByteArray(), 0, key.Value.Count);
                    return(record);
                }).ToList()
            });

            Dictionary <ByteString, Record> result = records.ToDictionary(record => record.Key);

            foreach (ByteString key in keyList)
            {
                if (!result.ContainsKey(key))
                {
                    result.Add(key, new Record(key, ByteString.Empty, ByteString.Empty));
                }
            }

            return(result.Values.ToList().AsReadOnly());
        }
        public void SqlRecordFillTest()
        {
            SqlMetaData[] metaData = new SqlMetaData[]
            {
                new SqlMetaData("col1", SqlDbType.Bit),
                new SqlMetaData("col2", SqlDbType.TinyInt),
                new SqlMetaData("col3", SqlDbType.VarBinary, 1000),
                new SqlMetaData("col4", SqlDbType.NVarChar, 1000),
                new SqlMetaData("col5", SqlDbType.DateTime),
                new SqlMetaData("col6", SqlDbType.Float),
                new SqlMetaData("col7", SqlDbType.UniqueIdentifier),
                new SqlMetaData("col8", SqlDbType.SmallInt),
                new SqlMetaData("col9", SqlDbType.Int),
                new SqlMetaData("col10", SqlDbType.BigInt),
                new SqlMetaData("col11", SqlDbType.Real),
                new SqlMetaData("col12", SqlDbType.Decimal),
                new SqlMetaData("col13", SqlDbType.Money),
                new SqlMetaData("col14", SqlDbType.Variant)
            };

            SqlDataRecord record = new SqlDataRecord(metaData);

            for (int i = 0; i < record.FieldCount; i++)
            {
                Assert.Equal($"col{i + 1}", record.GetName(i));
            }

            record.SetBoolean(0, true);
            Assert.Equal(true, record.GetBoolean(0));

            record.SetByte(1, 1);
            Assert.Equal(1, record.GetByte(1));

            byte[] bb1 = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            byte[] bb2 = new byte[5];
            record.SetSqlBinary(2, new SqlBinary(new byte[0]));
            record.SetBytes(2, 0, bb1, 0, 3);
            record.SetBytes(2, 2, bb1, 6, 3);

            // Verify the length of the byte array
            Assert.Equal(5, record.GetBytes(2, 0, bb2, 0, 5));

            Assert.Equal(5, record.GetBytes(2, 0, null, 0, 0));

            byte[] expected = new byte[] { 1, 2, 7, 8, 9 };
            Assert.Equal <byte>(expected, bb2);

            char[] cb1 = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
            char[] cb2 = new char[5];
            record.SetChars(3, 0, cb1, 0, 3);
            record.SetChars(3, 2, cb1, 4, 3);

            char[] expectedValue = new char[] { 'a', 'b', 'e', 'f', 'g' };
            Assert.Equal(expectedValue.Length, record.GetChars(3, 0, cb2, 0, 5));
            Assert.Equal <char>(expectedValue, new string(cb2, 0, (int)record.GetChars(3, 0, null, 0, 0)));

            record.SetString(3, "");
            string xyz = "xyz";

            record.SetString(3, "xyz");
            Assert.Equal(xyz, record.GetString(3));
            Assert.Equal(xyz.Length, record.GetChars(3, 0, cb2, 0, 5));
            Assert.Equal(xyz, new string(cb2, 0, (int)record.GetChars(3, 0, null, 0, 0)));

            record.SetChars(3, 2, cb1, 4, 3);
            Assert.Equal(5, record.GetChars(3, 0, cb2, 0, 5));

            string interleavedResult = "xyefg";

            Assert.Equal(interleavedResult, new string(cb2, 0, (int)record.GetChars(3, 0, null, 0, 0)));
            Assert.Equal(interleavedResult, record.GetString(3));

            record.SetSqlDateTime(4, SqlDateTime.MaxValue);
            Assert.Equal(SqlDateTime.MaxValue, record.GetSqlDateTime(4));

            record.SetSqlDouble(5, SqlDouble.MaxValue);
            Assert.Equal(SqlDouble.MaxValue, record.GetSqlDouble(5));

            SqlGuid guid = new SqlGuid("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");

            record.SetSqlGuid(6, guid);
            Assert.Equal(guid, record.GetSqlGuid(6));

            record.SetSqlInt16(7, SqlInt16.MaxValue);
            Assert.Equal(SqlInt16.MaxValue, record.GetSqlInt16(7));

            record.SetSqlInt32(8, SqlInt32.MaxValue);
            Assert.Equal(SqlInt32.MaxValue, record.GetSqlInt32(8));

            record.SetSqlInt64(9, SqlInt64.MaxValue);
            Assert.Equal(SqlInt64.MaxValue, record.GetSqlInt64(9));

            record.SetSqlSingle(10, SqlSingle.MinValue);
            Assert.Equal(SqlSingle.MinValue, record.GetSqlSingle(10));

            record.SetSqlDecimal(11, SqlDecimal.Null);
            record.SetSqlDecimal(11, SqlDecimal.MaxValue);
            Assert.Equal(SqlDecimal.MaxValue, record.GetSqlDecimal(11));

            record.SetSqlMoney(12, SqlMoney.MaxValue);
            Assert.Equal(SqlMoney.MaxValue, record.GetSqlMoney(12));


            // Try adding different values to SqlVariant type
            for (int i = 0; i < record.FieldCount - 1; ++i)
            {
                object valueToSet = record.GetSqlValue(i);
                record.SetValue(record.FieldCount - 1, valueToSet);
                object o = record.GetSqlValue(record.FieldCount - 1);

                if (o is SqlBinary)
                {
                    Assert.Equal <byte>(((SqlBinary)valueToSet).Value, ((SqlBinary)o).Value);
                }
                else
                {
                    Assert.Equal(valueToSet, o);
                }

                record.SetDBNull(record.FieldCount - 1);
                Assert.Equal(DBNull.Value, record.GetSqlValue(record.FieldCount - 1));

                record.SetDBNull(i);
                Assert.Equal(DBNull.Value, record.GetValue(i));
            }
        }
Exemplo n.º 13
0
        public static void GetTable(string connectionString, string tableName)
        {
            var metaCount  = 0;
            var fieldNames = new List <string>();

            //--use: "Provider=Microsoft.SQLSERVER.MOBILE.OLEDB.3.0;OLE DB Services=-4;" for SQL Compact 3.1
            //--use: "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;OLE DB Services=-4;" for SQL Compact 3.5 SP2
            //--use: "Provider=Microsoft.SQLSERVER.CE.OLEDB.4.0;OLE DB Services=-4;" for SQL Compact 4.0
            using (var conn = new OleDbConnection(connectionString))
            {
                conn.Open();

                // determine the number of SqlMetadata parameters needed
                using (var cmd = new OleDbCommand())
                {
                    cmd.CommandText = "SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @p1 ORDER BY ORDINAL_POSITION";
                    cmd.Parameters.Add(new OleDbParameter("@p1", OleDbType.VarWChar, 128));
                    cmd.Parameters[0].Value = tableName;
                    cmd.Connection          = conn;
                    using (var rdr = cmd.ExecuteReader())
                    {
                        while (rdr != null && rdr.Read())
                        {
                            //if (SqlContext.Pipe != null) SqlContext.Pipe.Send(rdr[1].ToString());
                            if (rdr[1].ToString() == "ntext" || rdr[1].ToString() == "image")
                            {
                                continue;
                            }
                            metaCount++;
                            fieldNames.Add("[" + rdr[0] + "]");
                        }
                    }
                }
                if (metaCount == 0)
                {
                    if (SqlContext.Pipe != null)
                    {
                        SqlContext.Pipe.Send("No data found, or table does not exist");
                    }
                    return;
                }

                //Get the meta data for the fields
                var metadata = GetMetaData(metaCount, tableName, conn);
                var record   = new SqlDataRecord(metadata);
                var fields   = new System.Text.StringBuilder();
                foreach (var field in fieldNames)
                {
                    fields.Append(field);
                    fields.Append(", ");
                }
                fields.Remove(fields.Length - 2, 2);

                using (var cmd = new OleDbCommand("SELECT " + fields + " FROM [" + tableName + "]", conn))
                {
                    using (var rdr = cmd.ExecuteReader())
                    {
                        if (SqlContext.Pipe != null)
                        {
                            //SqlContext.Pipe.Send(cmd.CommandText);
                            SqlContext.Pipe.SendResultsStart(record);
                            while (rdr != null && rdr.Read())
                            {
                                for (var i = 0; i < rdr.FieldCount; i++)
                                {
                                    if (rdr.IsDBNull(i))
                                    {
                                        record.SetDBNull(i);
                                    }
                                    else
                                    {
                                        if (metadata[i].SqlDbType == SqlDbType.Bit)
                                        {
                                            record.SetBoolean(i, rdr.GetBoolean(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.TinyInt)
                                        {
                                            record.SetByte(i, rdr.GetByte(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.SmallInt)
                                        {
                                            record.SetInt16(i, rdr.GetInt16(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.Int)
                                        {
                                            record.SetInt32(i, rdr.GetInt32(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.BigInt)
                                        {
                                            record.SetInt64(i, rdr.GetInt64(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.NVarChar || metadata[i].SqlDbType == SqlDbType.NChar)
                                        {
                                            record.SetString(i, rdr.GetString(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.UniqueIdentifier)
                                        {
                                            record.SetGuid(i, rdr.GetGuid(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.Timestamp || metadata[i].SqlDbType == SqlDbType.Binary || metadata[i].SqlDbType == SqlDbType.VarBinary)
                                        {
                                            var tsbuffer = (byte[])rdr[i];
                                            record.SetBytes(i, 0, tsbuffer, 0, tsbuffer.Length);
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.DateTime)
                                        {
                                            record.SetDateTime(i, rdr.GetDateTime(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.Money || metadata[i].SqlDbType == SqlDbType.Decimal)
                                        {
                                            record.SetDecimal(i, rdr.GetDecimal(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.Float)
                                        {
                                            record.SetDouble(i, rdr.GetDouble(i));
                                        }
                                        if (metadata[i].SqlDbType == SqlDbType.Real)
                                        {
                                            record.SetSqlSingle(i, Convert.ToSingle(rdr.GetValue(i)));
                                        }
                                    }
                                }
                                //Send the completed record..
                                SqlContext.Pipe.SendResultsRow(record);
                            }
                            if (rdr != null)
                            {
                                rdr.Close();
                            }
                            SqlContext.Pipe.SendResultsEnd();
                        }
                    }
                }
                conn.Close();
            }
        }
Exemplo n.º 14
0
 public override void Set(SqlDataRecord record, int ordinal, byte[] value)
 {
     record.SetBytes(ordinal, fieldOffset: 0, value, bufferOffset: 0, value.Length);
 }
        void SetValue(SqlDataRecord record, int position, Type type, object value)
        {
            switch (type.Name)
            {
            case "Int16":
                record.SetInt16(position, (short)value);
                break;

            case "Int32":
                record.SetInt32(position, (int)value);
                break;

            case "Int64":
                record.SetInt64(position, (long)value);
                break;

            case "Boolean":
                record.SetBoolean(position, (bool)value);
                break;

            case "Byte":
                record.SetByte(position, (byte)value);
                break;

            case "Bytes[]":
                record.SetBytes(position, 0, (byte[])value, 0, ((byte[])value).Length);
                break;

            case "Char":
                record.SetChar(position, (char)value);
                break;

            case "Char[]":
                record.SetChars(position, 0, (char[])value, 0, ((char[])value).Length);
                break;

            case "DateTime":
                record.SetDateTime(position, (DateTime)value);
                break;

            case "Decimal":
                record.SetDecimal(position, (decimal)value);
                break;

            case "Double":
                record.SetDouble(position, (double)value);
                break;

            case "Guid":
                record.SetGuid(position, (Guid)value);
                break;

            case "String":
                record.SetSqlString(position, (string)value);
                break;

            default:
                record.SetValue(position, value);
                break;
            }
        }
        /// <summary>
        /// Sets the bytes.
        /// </summary>
        /// <param name="record">The record.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <param name="fieldOffset">The field offset.</param>
        /// <param name="buffer">The buffer.</param>
        /// <param name="bufferOffset">The buffer offset.</param>
        /// <param name="length">The length.</param>
        public static void SetBytes(this SqlDataRecord record, string fieldName, long fieldOffset, byte[] buffer, int bufferOffset, int length)
        {
            int ordinal = GetOrdinal(record, fieldName);

            record.SetBytes(ordinal, fieldOffset, buffer, bufferOffset, length);
        }
Exemplo n.º 17
0
    /// <summary>
    /// Searches Active Directory according provided parameters
    /// </summary>
    /// <param name="userName">UserName to be used to authenticate AD</param>
    /// <param name="password">Password to be used to authenticate to AD</param>
    /// <param name="authType">Authentication type to be used to authenticate to AD</param>
    /// <param name="adRoot">AD Root for querying AD</param>
    /// <param name="filter">Filter to be used for querying</param>
    /// <param name="searchScope">Scope to be used for queryingg</param>
    /// <param name="propertiesToLoad">List of properties to return</param>
    /// <param name="pageSize">Represents a PageSise for the paged search of AD</param>
    /// <param name="rowsLimit">Rrepresent limit for numbers of rows returned. NULL or value less than 1 represents unlimited</param>
    private static void SearchAD(string userName, string password, string authType, string adRoot, string filter, string searchScope, string propertiesToLoad, int pageSize, SqlInt32 rowsLimit)
    {
        string[]         properties     = propertiesToLoad.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
        ADPropertyInfo[] adProperties   = new ADPropertyInfo[properties.Length];
        SqlMetaData[]    recordMetaData = new SqlMetaData[properties.Length];
        SearchScope      scope;
        Type             et = typeof(Encoding); //Encoding Type

        int limit     = rowsLimit.IsNull ? 0 : rowsLimit.Value;
        int rowsCount = 0;

        if (rowsLimit > 0 && pageSize > limit)
        {
            pageSize = limit;
        }

        if (!TryParseEnum <SearchScope>(searchScope, true, out scope))
        {
            throw new System.InvalidCastException(string.Format("searchScope must be one of '{0}'", GetEnumNames <SearchScope>()));
        }


        //Trim properties and prepare result set metadata, also process specified lengths
        for (int i = 0; i < properties.Length; i++)
        {
            string[] propDetails = properties[i].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);  //Properties detals - Split to Name, Length, Decoder and Encoder
            string   propName    = propDetails[0].Trim();
            int      len         = 4000;
            int      tmpLen;
            bool     isBinary        = false;
            Encoding decoder         = Encoding.Unicode;
            Encoding encoder         = Encoding.Unicode;
            bool     encodingBiinary = false;

            #region Field Length Retrieval

            if (propDetails.Length > 1)
            {
                //if length is "max" then set len = -1 whihc equals to MAX
                if (propDetails[1].ToLower() == "max")
                {
                    len = -1;
                }
                else if (int.TryParse(propDetails[1], out tmpLen) && tmpLen >= 1 && tmpLen <= 4000)
                {
                    len = tmpLen;
                }
                else
                {
                    throw new System.InvalidCastException(string.Format("[{0}] - Length of field has to be numeric value in range 1 - 4000 or max", properties[i]));
                }
            }

            #endregion

            #region Get Decoder and Encoder
            //find Encoding
            if (propDetails.Length >= 3)
            {
                decoder = null;
                Exception exc = null;

                //If Decoder or Encoder is BINARY then we will use a binary storage
                if (propDetails[2] == "BINARY" || (propDetails.Length >= 4 && propDetails[3] == "BINARY"))
                {
                    isBinary = true;
                }

                if (propDetails.Length >= 4 && propDetails[3] == "BINARY")
                {
                    encodingBiinary = true;
                }

                //Get Decoder
                if (propDetails[2] != "BINARY")
                {
                    int codePage;
                    try
                    {
                        if (int.TryParse(propDetails[2].Trim(), out codePage))
                        {
                            decoder = Encoding.GetEncoding(codePage);
                        }
                        else
                        {
                            //Try to get static property of the Encoding Class
                            System.Reflection.PropertyInfo pi = et.GetProperty(propDetails[2].Trim(), et);

                            //if the static property does not exists, treats the name as Code Page name
                            if (pi == null)
                            {
                                decoder = Encoding.GetEncoding(propDetails[2].Trim());
                            }
                            else if (pi.CanRead)
                            {
                                decoder = pi.GetValue(null, null) as Encoding;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        exc = e;
                    }

                    if (decoder == null)
                    {
                        //Get List of available static properties of the EncodingClass
                        StringBuilder sb = new StringBuilder();
                        sb.Append("BINARY");

                        foreach (PropertyInfo p in et.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static))
                        {
                            if (p.PropertyType == et)
                            {
                                sb.Append(",");
                                sb.Append(p.Name);
                            }
                        }
                        throw new System.NotSupportedException(string.Format("[{0}] - Decoder has to be one of {1} or a CodePage Numer or CodePage name. For Code Pages see http://msdn.microsoft.com/en-us/library/vstudio/system.text.encoding(v=vs.100).aspx", properties[i], sb.ToString()), exc);
                    }
                }

                //Get Encoder
                if (propDetails.Length >= 4 && propDetails[3] != "BINARY")
                {
                    encoder = null;
                    int codePage;

                    try
                    {
                        //In case of CodePage number, try to get code page
                        if (int.TryParse(propDetails[3].Trim(), out codePage))
                        {
                            encoder = Encoding.GetEncoding(codePage);
                        }
                        else
                        {
                            //Try to get static property of the Encoding Class
                            System.Reflection.PropertyInfo pi = et.GetProperty(propDetails[2].Trim(), et);

                            //if the static property does not exists, treats the name as Code Page name
                            if (pi == null)
                            {
                                encoder = Encoding.GetEncoding(propDetails[2].Trim());
                            }
                            else if (pi.CanRead)
                            {
                                encoder = pi.GetValue(null, null) as Encoding;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        exc = e;
                    }

                    if (encoder == null)
                    {
                        //Get List of available static properties of the EncodingClass
                        StringBuilder sb = new StringBuilder();
                        sb.Append("BINARY");

                        foreach (PropertyInfo p in et.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static))
                        {
                            if (p.PropertyType == et)
                            {
                                sb.Append(",");
                                sb.Append(p.Name);
                            }
                        }
                        throw new System.NotSupportedException(string.Format("[{0}] - Encoder has to be one of {1} or a CodePage Numer or CodePage name. For Code Pages see http://msdn.microsoft.com/en-us/library/vstudio/system.text.encoding(v=vs.100).aspx", properties[i], sb.ToString()), exc);
                    }
                }
            }
            #endregion

            //IF Binary, use VarBinary data type otherwise NVarChar
            if (isBinary)
            {
                recordMetaData[i] = new SqlMetaData(propName, System.Data.SqlDbType.VarBinary, len);
            }
            else
            {
                recordMetaData[i] = new SqlMetaData(propName, System.Data.SqlDbType.NVarChar, len);
            }

            //Set ADProperties for current property
            adProperties[i] = new ADPropertyInfo(propName, len, decoder, encoder, isBinary, encodingBiinary);
            properties[i]   = propName;
        }

        //Get Root Directory Entry
        using (DirectoryEntry rootEntry = GetRootEntry(adRoot, userName, password, authType))
        {
            //Create a directory searcher with aproperiate filter, properties and search scope
            using (DirectorySearcher ds = new DirectorySearcher(rootEntry, filter, properties, scope))
            {
                if (pageSize > 0)
                {
                    ds.PageSize = pageSize; //Set Page Size - without this we will not do a paged search and we will be limiited to 1000 results
                }
                //find all object from the rood, according the filter and search scope
                using (SearchResultCollection results = ds.FindAll())
                {
                    SqlDataRecord record = new SqlDataRecord(recordMetaData);
                    //Start pushing of records to client
                    SqlContext.Pipe.SendResultsStart(record);

                    Regex dnr = null;

                    foreach (SearchResult result in results)
                    {
                        record = new SqlDataRecord(recordMetaData);

                        for (int i = 0; i < properties.Length; i++)
                        {
                            ADPropertyInfo adProperty = adProperties[i];

                            ResultPropertyValueCollection props = result.Properties[adProperty.PropertyName];
                            if (props.Count == 1)           //if property collection contains single vallue, set the record field to that value
                            {
                                if (props[0] is byte[])
                                {
                                    byte[] buffer = props[0] as byte[];

                                    if (adProperty.IsBinary) //If Binary output, write binary buffer
                                    {
                                        record.SetBytes(i, 0, buffer, 0, adProperty.Length != -1 && adProperty.Length < buffer.Length ? adProperty.Length : buffer.Length);
                                    }
                                    else //Otherwise use decoder to decode the buffer to sctring
                                    {
                                        record.SetSqlString(i, adProperty.Decoder.GetString(buffer));
                                    }
                                }
                                else
                                {
                                    if (adProperty.IsBinary) //In case of binary output, Encode binary to bytes array
                                    {
                                        var buffer = adProperty.Encoder.GetBytes(props[0].ToString());
                                        record.SetBytes(i, 0, buffer, 0, adProperty.Length != -1 && adProperty.Length < buffer.Length ? adProperty.Length : buffer.Length);
                                    }
                                    else
                                    {
                                        record.SetSqlString(i, props[0].ToString());
                                    }
                                }
                            }

                            else if (props.Count == 0)      //if property collection doesn't contain any value, set record field to NULL
                            {
                                //In case Distinguished Name was requested and such attribute is not in the LDAP, parse the result.Path
                                if (adProperty.PropertyName.ToLower() == "dn" || adProperty.PropertyName.ToLower() == "distinguishedname")
                                {
                                    if (dnr == null)
                                    {
                                        dnr = new Regex(@"(?:.+?)//(?:(?:\w|\.)+?)/(?<dn>.+)", RegexOptions.Compiled); // LDAP://server_name_or_ip/DN
                                    }
                                    var match = dnr.Match(result.Path);
                                    if (match != null && match.Groups.Count > 1)
                                    {
                                        if (adProperty.IsBinary)
                                        {
                                            var buffer = adProperty.Encoder.GetBytes(match.Groups["dn"].Value);
                                            record.SetBytes(i, 0, buffer, 0, adProperty.Length != -1 && adProperty.Length < buffer.Length ? adProperty.Length : buffer.Length);
                                        }
                                        else
                                        {
                                            record.SetSqlString(i, match.Groups["dn"].Value);
                                        }
                                    }
                                }
                                else
                                {
                                    if (adProperty.IsBinary)
                                    {
                                        record.SetSqlBinary(i, SqlBinary.Null);
                                    }
                                    else
                                    {
                                        record.SetSqlString(i, SqlString.Null);
                                    }
                                }
                            }
                            else                                                       //In case of multiple value, separate the values by commas
                            {
                                if (adProperty.IsBinary)                               //In case of Binary output, create a MemoryStream to which we write multiple binary values and the store the data in the output field
                                {
                                    using (MemoryStream ms = new MemoryStream())       //MemoryStream to store the binary data
                                    {
                                        using (BinaryWriter bw = new BinaryWriter(ms)) //Binary write for writin the data into the memory stream
                                        {
                                            foreach (object prop in props)
                                            {
                                                if (prop is byte[]) //If property is byte array, write that byte array into the memory stream
                                                {
                                                    bw.Write((byte[])prop);
                                                }
                                                else
                                                {
                                                    if (adProperty.EncodeBinary) //If BinaryEncoded, user the BinaryWrite.Write(string)
                                                    {
                                                        bw.Write(prop.ToString());
                                                    }
                                                    else //Otherwise use Encoder to encode the string into byte array and write it iinto the memory stream
                                                    {
                                                        bw.Write(adProperty.Encoder.GetBytes(prop.ToString()));
                                                    }
                                                }
                                            }
                                        }
                                        //Get the MemoryStream buffer and write it into the output field
                                        var buffer = ms.GetBuffer();
                                        record.SetBytes(i, 0, buffer, 0, adProperty.Length != -1 && adProperty.Length < buffer.Length ? adProperty.Length : buffer.Length);
                                    }
                                }
                                else  //character output
                                {
                                    StringBuilder sb        = new StringBuilder();
                                    bool          firstItem = true;
                                    foreach (object prop in props)
                                    {
                                        if (!firstItem)
                                        {
                                            sb.Append(',');
                                        }
                                        else
                                        {
                                            firstItem = false;
                                        }
                                        if (prop is byte[]) //In case of binary data, decode them to a string using decoder
                                        {
                                            sb.Append(adProperty.Decoder.GetString((byte[])prop));
                                        }
                                        else
                                        {
                                            sb.Append(prop.ToString());
                                        }
                                    }

                                    var c = sb.ToString();
                                    record.SetSqlString(i, sb.ToString());
                                }
                            }
                        }

                        //send record to client
                        SqlContext.Pipe.SendResultsRow(record);

                        //if rowsLimit was reached, break the loop
                        if (++rowsCount == rowsLimit)
                        {
                            break;
                        }
                    }

                    //stop sending records to client
                    SqlContext.Pipe.SendResultsEnd();
                }
            }
        }
    }