text:
layout:     post
title:      "Comprehensions in python"
subtitle:   "Dive into different comprehensions supported by python"
date:       2017-06-20 12:00:00
author:     "Akash"
header-img: "img/post-bg-nextgen-web-pwa.jpg"
header-mask: 0.3
catalog:    true
tags:
    - List
---

Comprehensions in python are one of the most widely used unique feature available to the language. In simple words, it is a one-liner used to replace a loop. Of course, we can have complex comprehensions that can replace nested loops.

Comprehensions available in python:
- List comprehension
- Dict comprehension
- Set comprehension

List comprehension

As the name suggests, a list comprehension is used to generate a list by iterating over a sequence with optional filtering. It is most commonly used among all 3 comprehensions available in python.

Syntax of creating a list comprehension:
{% highlight python %}
[<expression> for <element> in iterable if <one or more conditions>]
{% endhighlight %}

Example:
To make a list of all numbers between 1 to 100 that are divisible by both 3 and 5, we can write a comprehension like:
{% highlight python %}
nums = [num for num in range(1, 101) if num % 3 == 0 and num % 5 == 0]
{% endhighlight %}

Equivalent for-loop will for above logic will be:
{% highlight python %}
nums = []
for e in range(1, 101):
   if e % 3 == 0 and e % 5 == 0:
      nums.append()
{% endhighlight %}

Clearly, comprehension is more clear and concise.

Nested list comprehension

Nested loop can be easily replaced by a nested list comprehension.
Example:
{% highlight python %}
combi = []
for i in range(1, 3):
   for j in range(7, 9):
      combi.append((i, j))
{% endhighlight %}

It will produce following list
{% highlight python %}
[(1,7), (1,8), (2,7), (2,8)]
{% endhighlight %}

Equivalent comprehension:
{% highlight python %}
[(i,j) for i in range(1, 3) for j in range(7, 9)]
{% endhighlight %}

Note: In a nested comprehension, order of iterables will be same as one that will be in a conventional loop. In the above example, for-loop is having 'i' in outer loop and 'j' in inner loop. Therefore, same order is followed in the comprehension as well.

Matrix using nested comprehension

Natively python doesn't support a multi-dimenisonal array but same can be achieved with a list of lists where each list represents a row while the entire collection forms a matrix.

To create a 2-D matrix,
{% highlight python %}
matx = [[x for x in range(3)] for _ in range (3)]
print '\n'.join(matx)
{% endhighlight %}
Output:
{% highlight python %}
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
{% endhighlight %}

Dict comprehension

Python also supports creating a dict in simliar fashion as a list comprehension.
Syntax of creating a dicy comprehension:
{% highlight python %}
[<expression_1>:<expression_2> for <element> in iterable if <one or more conditions>]
{% endhighlight %}

Set comprehension

Set comprehension is similar to list comprehension in terms of syntax and functionality with the difference that it outputs a set instead of a list.

Syntax of creating a list comprehension:
{% highlight python %}
{<expression> for <element> in iterable if <one or more conditions>}
{% endhighlight %}

References:

https://github.com/python/peps/blob/master/pep-0202.txt


text:
require 'spec_helper'

describe 'nova::network' do

  let :pre_condition do
    'include nova'
  end

  let :default_params do
    {
      :private_interface => 'eth1',
      :fixed_range       => '10.0.0.0/32',
    }
  end

  let :params do
    default_params
  end

  describe 'on debian platforms' do

    let :facts do
      { :osfamily => 'Debian' }
    end

    it { should contain_sysctl__value('net.ipv4.ip_forward').with_value('1') }

    describe 'when installing service' do

      it { should contain_package('nova-network').with(
        'name'   => 'nova-network',
        'ensure' => 'present',
        'notify' => 'Service[nova-network]'
      ) }

      describe 'with enabled as true' do
        let :params do
          default_params.merge(:enabled => true)
        end
        it { should contain_service('nova-network').with(
          'name'    => 'nova-network',
          'ensure'  => 'running',
          'enable'  => true
        )}
      end
      describe 'when enabled is set to false' do
        it { should contain_service('nova-network').with(
          'name'    => 'nova-network',
          'ensure'  => 'stopped',
          'enable'  => false
        )}
      end
    end
    describe 'when not installing service' do

      let :params do
        default_params.merge(:install_service => false)
      end

      it { should_not contain_package('nova-network') }
      it { should_not contain_service('nova-network') }

    end

    describe 'when not creating networks' do
      let :params do
        default_params.merge(:create_networks => false)
      end
      it { should_not contain_nova__manage__network('nova-vm-net') }
      it { should_not contain_nova__manage__floating('nova-vm-floating') }
    end

    describe 'when creating networks' do
      it { should contain_nova__manage__network('nova-vm-net').with(
        :network      => '10.0.0.0/32',
        :num_networks => '1'
      ) }
      it { should_not contain__nova__manage__floating('nova-vm-floating') }
      describe 'when number of networks is set' do
        let :params do
          default_params.merge(:num_networks => '2')
        end
        it { should contain_nova__manage__network('nova-vm-net').with(
          :num_networks => '2'
        ) }
      end
      describe 'when floating range is set' do
        let :params do
          default_params.merge(:floating_range => '10.0.0.0/30')
        end
        it { should contain_nova_config('DEFAULT/floating_range').with_value('10.0.0.0/30') }
        it { should contain_nova__manage__floating('nova-vm-floating').with_network('10.0.0.0/30') }
      end
    end
    describe 'when configuring networks' do
      describe 'when configuring flatdhcpmanager' do
        let :params do
          default_params.merge(:network_manager => 'nova.network.manager.FlatDHCPManager')
        end
        it { should contain_class('nova::network::flatdhcp').with(
          :fixed_range          => '10.0.0.0/32',
          :public_interface     => nil,
          :flat_interface       => 'eth1',
          :flat_network_bridge  => 'br100',
          :force_dhcp_release   => true,
          :flat_injected        => false,
          :dhcp_domain          => 'novalocal',
          :dhcpbridge           => '/usr/bin/nova-dhcpbridge',
          :dhcpbridge_flagfile  => '/etc/nova/nova.conf'
        ) }
        describe 'when overriding parameters' do
          let :params do
            default_params.merge(
              {
                :network_manager  => 'nova.network.manager.FlatDHCPManager',
                :public_interface => 'eth0',
                :config_overrides =>
                  {
                    'flat_network_bridge' => 'br400',
                    'force_dhcp_release'  => false,
                    'flat_injected'       => true,
                    'dhcp_domain'         => 'not-novalocal',
                    'dhcpbridge'          => '/tmp/bridge',
                    'dhcpbridge_flagfile' => '/tmp/file',
                  }
              }
            )
          end
          it { should contain_class('nova::network::flatdhcp').with(
            :fixed_range          => '10.0.0.0/32',
            :public_interface     => 'eth0',
            :flat_interface       => 'eth1',
            :flat_network_bridge  => 'br400',
            #:force_dhcp_release   => false,
            :flat_injected        => true,
            :dhcp_domain          => 'not-novalocal',
            :dhcpbridge           => '/tmp/bridge',
            :dhcpbridge_flagfile  => '/tmp/file'
          ) }

        end
      end
      describe 'when configuring flatmanager' do
        let :params do
          default_params.merge(:network_manager => 'nova.network.manager.FlatManager')
        end
        it { should contain_class('nova::network::flat').with(
          :fixed_range         => '10.0.0.0/32',
          :public_interface    => nil,
          :flat_interface      => 'eth1',
          :flat_network_bridge => 'br100'
        ) }
        describe 'when overriding flat network params' do
          let :params do
            default_params.merge(
              {
                :network_manager  => 'nova.network.manager.FlatManager',
                :public_interface => 'eth0',
                :config_overrides => {'flat_network_bridge' => 'br400' }
              }
            )
          end
          it { should contain_class('nova::network::flat').with(
            :public_interface    => 'eth0',
            :flat_network_bridge => 'br400'
          ) }
          end
      end
      describe 'when configuring vlan' do
        let :params do
          default_params.merge(:network_manager => 'nova.network.manager.VlanManager')
        end
        it { should contain_class('nova::network::vlan').with(
          :fixed_range         => '10.0.0.0/32',
          :public_interface    => nil,
          :vlan_interface      => 'eth1',
          :force_dhcp_release  => true,
          :dhcp_domain         => 'novalocal',
          :dhcpbridge          => '/usr/bin/nova-dhcpbridge',
          :dhcpbridge_flagfile => '/etc/nova/nova.conf'
        ) }
        describe 'when overriding parameters' do
          let :params do
            default_params.merge(
              {
              }
            )
          end
        end
      end
    end
    describe 'with package version' do
      let :params do
        default_params.merge(:ensure_package => '2012.1-2')
      end
      it { should contain_package('nova-network').with(
        'ensure' => '2012.1-2'
      )}
    end
  end
  describe 'on rhel' do
    let :facts do
      { :osfamily => 'RedHat' }
    end
    it { should contain_service('nova-network').with(
      'name'    => 'openstack-nova-network',
      'ensure'  => 'stopped',
      'enable'  => false
    )}
    it { should contain_package('nova-network').with_name('openstack-nova-network') }
  end
end

redpajama_set_name: RedPajamaGithub


text:
'use strict';

/**
 * Session module
 */

const db = require('../database');
const path = require('path');
const uuidV4 = require('uuid/v4');
const config = require('../../config.json');
const fs = require('fs-extra');
const Promise = require('bluebird');
const _ = require('lodash');

const ensureDir = Promise.promisify(fs.ensureDir);

const createDirectories = (id) =>
  Promise.all(_.map(config.directories, (directory, key) =>
    ensureDir(path.join(directory, id))
      .then((createdDirectory) => ({ key, createdDirectory, directory }))))
    .then(directories =>
      directories.reduce((result, { key, directory }) => {
        const sessionDirectory = {};
        sessionDirectory[key] = path.join(directory, id);
        Object.assign(result, sessionDirectory);
        return result;
      }, {}));

const create = () => {
  const id = uuidV4();
  return db.insertSession({ id })
    .then(() => createDirectories(id))
    .then((directories) => ({
      session: id,
      directories,
    }));
};

module.exports = {
  create,
};


text:
/*************************************************************************
 *
 * Hxj.Data
 *
 * 2010-2-10
 *
 * steven hu
 *
 * Support: http://www.cnblogs.com/huxj
 *
 *
 * Change History:
 *
 *
**************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using Dos.ORM.Common;
using System.Web;
using System.Web.Caching;

namespace Dos.ORM
{

    /// <summary>
    /// 查询
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class FromSection<T> : FromSection
        where T : Entity
    {

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="database"></param>
        public FromSection(Database database)
            : this(database, (DbTransaction)null)
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="database"></param>
        /// <param name="trans"></param>
        public FromSection(Database database, DbTransaction trans)
            : base(database, database.DbProvider.BuildTableName(EntityCache.GetTableName<T>()), trans)
        {

        }

        #region 连接  join

        /// <summary>
        /// Inner Join。Lambda写法:.InnerJoin<Model2>((d1,d2) => d1.ID == d2.ID)
        /// </summary>
        public FromSection<T> InnerJoin<TEntity>(WhereClip where)
             where TEntity : Entity
        {
            return join(EntityCache.GetTableName<TEntity>(), where, JoinType.InnerJoin);
        }

        /// <summary>
        /// Cross Join
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection<T> CrossJoin<TEntity>(WhereClip where)
            where TEntity : Entity
        {
            return join(EntityCache.GetTableName<TEntity>(), where, JoinType.CrossJoin);
        }
        /// <summary>
        /// Right Join
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection<T> RightJoin<TEntity>(WhereClip where)
            where TEntity : Entity
        {
            return join(EntityCache.GetTableName<TEntity>(), where, JoinType.RightJoin);
        }

        /// <summary>
        /// Left Join。经典写法:Model1._.ID == Model2._.ID
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection<T> LeftJoin<TEntity>(WhereClip where)
             where TEntity : Entity
        {
            return join(EntityCache.GetTableName<TEntity>(), where, JoinType.LeftJoin);
        }
        /// <summary>
        /// Full Join
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection<T> FullJoin<TEntity>(WhereClip where)
            where TEntity : Entity
        {
            return join(EntityCache.GetTableName<TEntity>(), where, JoinType.FullJoin);
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="where"></param>
        /// <param name="joinType"></param>
        /// <returns></returns>
        private new FromSection<T> join(string tableName, WhereClip where, JoinType joinType)
        {
            return (FromSection<T>)base.join(tableName, where, joinType);

            //if (string.IsNullOrEmpty(tableName) || WhereClip.IsNullOrEmpty(where))
            //    return this;

            //tableName = dbProvider.BuildTableName(tableName);

            //if (!joins.ContainsKey(tableName))
            //{
            //    string joinString = string.Empty;
            //    switch (joinType)
            //    {
            //        case JoinType.InnerJoin:
            //            joinString = "INNER JOIN";
            //            break;
            //        case JoinType.LeftJoin:
            //            joinString = "LEFT OUTER JOIN";
            //            break;
            //        case JoinType.RightJoin:
            //            joinString = "RIGHT OUTER JOIN";
            //            break;
            //        case JoinType.CrossJoin:
            //            joinString = "CROSS JOIN";
            //            break;
            //        case JoinType.FullJoin:
            //            joinString = "FULL OUTER JOIN";
            //            break;
            //        default:
            //            joinString = "INNER JOIN";
            //            break;
            //    }

            //    joins.Add(tableName, new KeyValuePair<string, WhereClip>(joinString, where));
            //}

            //return this;
        }

        #endregion

        #region 私有方法

        /// <summary>
        ///  设置默认主键排序
        /// </summary>
        private void setPrimarykeyOrderby()
        {

            Field[] primarykeys = EntityCache.GetPrimaryKeyFields<T>();

            OrderByClip temporderBy;

            if (null != primarykeys && primarykeys.Length > 0)
            {
                temporderBy = new OrderByClip(primarykeys[0]);
            }
            else
            {
                temporderBy = new OrderByClip(EntityCache.GetFirstField<T>());
            }

            OrderBy(temporderBy);
        }

        #endregion

        #region 操作

        /// <summary>
        /// Having
        /// </summary>
        public new FromSection<T> Having(WhereClip havingWhere)
        {
            return (FromSection<T>)base.Having(havingWhere);
        }
        /// <summary>
        /// whereclip
        /// </summary>
        public new FromSection<T> Where(WhereClip where)
        {
            return (FromSection<T>)base.Where(where);
        }
        /// <summary>
        /// groupby
        /// </summary>
        public new FromSection<T> GroupBy(GroupByClip groupBy)
        {
            return (FromSection<T>)base.GroupBy(groupBy);
        }
        /// <summary>
        /// groupby
        /// </summary>
        public new FromSection<T> GroupBy(params Field[] fields)
        {
            return (FromSection<T>)base.GroupBy(fields);
        }
        #region 2015-09-08新增
        /// <summary>
        ///
        /// </summary>
        public new FromSection<T> OrderBy(params Field[] f)
        {
            var gb = OrderByClip.None;
            foreach (var field in f)
            {
                gb = gb && field.Asc;
            }
            return (FromSection<T>)base.OrderBy(gb);
        }
        /// <summary>
        ///
        /// </summary>
        public new FromSection<T> OrderByDescending(params Field[] f)
        {
            var gb = OrderByClip.None;
            foreach (var field in f)
            {
                gb = gb && field.Desc;
            }
            return (FromSection<T>)base.OrderBy(gb);
        }
        #endregion
        /// <summary>
        ///
        /// </summary>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        public new FromSection<T> OrderBy(OrderByClip orderBy)
        {
            return (FromSection<T>)base.OrderBy(orderBy);
        }
        /// <summary>
        /// orderby
        /// </summary>
        public new FromSection<T> OrderBy(params OrderByClip[] orderBys)
        {
            return (FromSection<T>)base.OrderBy(orderBys);
        }
        /// <summary>
        /// select field
        /// </summary>
        public new FromSection<T> Select(params Field[] fields)
        {
            return (FromSection<T>)base.Select(fields);
        }
        /// <summary>
        /// Distinct
        /// </summary>
        /// <returns></returns>
        public new FromSection<T> Distinct()
        {
            return (FromSection<T>)base.Distinct();
        }

        /// <summary>
        /// Top
        /// </summary>
        /// <param name="topCount"></param>
        /// <returns></returns>
        public new FromSection<T> Top(int topCount)
        {
            return From(1, topCount);
        }

        /// <summary>
        /// Page
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        public new FromSection<T> Page(int pageSize, int pageIndex)
        {
            return From(pageSize * (pageIndex - 1) + 1, pageIndex * pageSize);
        }

        /// <summary>
        /// 设置默认排序
        /// </summary>
        private void setDefaultOrderby()
        {
            if (OrderByClip.IsNullOrEmpty(this.OrderByClip))
            {
                if (fields.Count > 0)
                {
                    foreach (Field f in fields)
                    {
                        if (f.PropertyName.Trim().Equals("*"))
                        {
                            setPrimarykeyOrderby();
                            break;
                        }
                    }

                }
                else
                {
                    setPrimarykeyOrderby();
                }
            }
        }

        /// <summary>
        /// From  1-10
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns></returns>
        public new FromSection<T> From(int startIndex, int endIndex)
        {
            if (startIndex > 1)
            {
                setDefaultOrderby();
            }

            return (FromSection<T>)base.From(startIndex, endIndex);
            //return (FromSection<T>)dbProvider.CreatePageFromSection(this, startIndex, endIndex);
        }

        /// <summary>
        /// 设置缓存有效期  单位:秒
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public new FromSection<T> SetCacheTimeOut(int timeout)
        {
            this.timeout = timeout;
            return this;
        }

        /// <summary>
        /// 设置缓存依赖
        /// </summary>
        /// <param name="dep"></param>
        /// <returns></returns>
        public new FromSection<T> SetCacheDependency(CacheDependency dep)
        {
            this.cacheDep = dep;
            return this;
        }

        /// <summary>
        /// 重新加载
        /// </summary>
        /// <returns></returns>
        public new FromSection<T> Refresh()
        {
            isRefresh = true;
            return this;
        }

        /// <summary>
        /// select sql
        /// </summary>
        /// <param name="fromSection"></param>
        /// <returns></returns>
        public new FromSection<T> AddSelect(FromSection fromSection)
        {
            return AddSelect(fromSection, null);
        }

        /// <summary>
        /// select sql
        /// </summary>
        /// <param name="fromSection"></param>
        /// <param name="aliasName">别名</param>
        /// <returns></returns>
        public new FromSection<T> AddSelect(FromSection fromSection, string aliasName)
        {
            return (FromSection<T>)base.AddSelect(fromSection, aliasName);
        }

        #endregion

        #region 查询
        private readonly string[] notClass = new string[] { "String" };
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        public List<TResult> ToList<TResult>()
        {
            var typet = typeof(TResult);
            if (typet == typeof(T))
            {
                return ToList() as List<TResult>;
            }
            FromSection from = getPagedFromSection();
            if (typet.IsClass && !((IList) notClass).Contains(typet.Name))
            {
                string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "List", "|",
                    formatSql(from.SqlString, from));
                object cacheValue = getCache(cacheKey);

                if (null != cacheValue)
                {
                    return (List<TResult>)cacheValue;
                }
                List<TResult> list = new List<TResult>();
                using (IDataReader reader = ToDataReader(from))
                {
                    list = EntityUtils.Mapper.Map<TResult>(reader);
                    reader.Close();
                }
                setCache<List<TResult>>(list, cacheKey);
                return list;
            }
            if (@from.Fields.Count == 0)
            {
                throw new Exception(".ToList<" + typet.Name + ">()至少需要.Select()一个字段!");
            }
            else if (@from.Fields.Count > 1)
            {
                throw new Exception(".ToList<" + typet.Name + ">()最多.Select()一个字段!");
            }
            else
            {
                string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "List", "|",
                    formatSql(@from.SqlString, @from));
                object cacheValue = getCache(cacheKey);

                if (null != cacheValue)
                {
                    return (List<TResult>)cacheValue;
                }
                List<TResult> list = new List<TResult>();
                using (IDataReader reader = ToDataReader(@from))
                {
                    while (reader.Read())
                    {
                        list.Add(DataUtils.ConvertValue<TResult>(reader[@from.Fields[0].Name]));
                    }
                    reader.Close();
                }
                setCache<List<TResult>>(list, cacheKey);
                return list;
            }
        }

        /// <summary>
        /// To List<T>
        /// </summary>
        /// <returns></returns>
        public List<T> ToList()
        {
            FromSection from = getPagedFromSection();
            string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "List", "|", formatSql(from.SqlString, from));
            object cacheValue = getCache(cacheKey);
            if (null != cacheValue)
            {
                return (List<T>)cacheValue;
            }
            List<T> list = new List<T>();
            using (IDataReader reader = ToDataReader(from))
            {
                list = EntityUtils.Mapper.Map<T>(reader);
                #region 2015-08-10注释
                //if (@from.Joins.Any() || from.Fields.Any())
                //{
                //    //list = new EmitMapper.Mappers.DataReaderToObjectMapper<T>().ReadCollection(reader).ToList();
                //    //while (reader.Read())
                //    //{
                //    //    T t = EmitMapper.ObjectMapperManager.DefaultInstance.GetMapper<IDataReader, T>().Map(reader);
                //    //    list.Add(t);
                //    //}
                //    //DataRecordInternal
                //    //T result = MapUsingState(reader, reader);
                //    //list = EmitMapper.ObjectMapperManager.DefaultInstance.GetMapper<IDataReader, List<T>>().Map(reader);
                //    list = EntityUtils.Mapper.Map<T>(reader);
                //}
                //else
                //{
                //    while (reader.Read())
                //    {
                //        T t = DataUtils.Create<T>();
                //        t.SetPropertyValues(reader);
                //        list.Add(t);
                //    }
                //}
                #endregion
                reader.Close();
            }
            setCache<List<T>>(list, cacheKey);
            //2015-09-08
            if (list != null)
            {
                foreach (var m in list)
                {
                    m.ClearModifyFields();
                }
            }

            return list;
        }

        /// <summary>
        /// 返回第一个实体  如果为null,则默认实例化一个
        /// </summary>
        /// <returns></returns>
        public T ToFirstDefault()
        {
            T t = this.ToFirst();
            if (t == null)
                t = DataUtils.Create<T>();
            return t;
        }

        /// <summary>
        /// 返回第一个实体,同ToFirst()。无数据返回Null。
        /// </summary>
        /// <returns></returns>
        public T First()
        {
            return ToFirst();
        }
        /// <summary>
        /// 返回第一个实体,同ToFirst()。无数据返回Null。
        /// </summary>
        /// <returns></returns>
        public TResult First<TResult>() where TResult : class
        {
            return ToFirst<TResult>();
        }
        /// <summary>
        /// 返回第一个实体 ,同First()。无数据返回Null。
        /// </summary>
        /// <returns></returns>
        public TResult ToFirst<TResult>() where TResult : class
        {
            var typet = typeof(TResult);
            if (typet == typeof(T))
            {
                return ToFirst() as TResult;
            }
            FromSection from = this.Top(1).getPagedFromSection();
            string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "FirstT", "|", formatSql(from.SqlString, from));
            object cacheValue = getCache(cacheKey);

            if (null != cacheValue)
            {
                return (TResult)cacheValue;
            }

            TResult t = default(TResult);
            using (IDataReader reader = ToDataReader(from))
            {
                var tempt = EntityUtils.Mapper.Map<TResult>(reader);
                if (tempt.Count > 0)
                {
                    t = tempt[0];
                }
                reader.Close();
            }

            setCache<TResult>(t, cacheKey);
            return t;
        }
        /// <summary>
        /// 返回第一个实体 ,同First()。无数据返回Null。
        /// </summary>
        /// <returns></returns>
        public T ToFirst()
        {
            FromSection from = this.Top(1).getPagedFromSection();
            string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "FirstT", "|", formatSql(from.SqlString, from));
            object cacheValue = getCache(cacheKey);

            if (null != cacheValue)
            {
                return (T)cacheValue;
            }

            T t = null;
            using (IDataReader reader = ToDataReader(from))
            {
                var tempt = EntityUtils.Mapper.Map<T>(reader);
                if (tempt.Count > 0)
                {
                    t = tempt[0];
                }
                #region 2015-08-10注释
                //if (@from.Joins.Any() || from.Fields.Any())
                //{
                //    var tempt = EntityUtils.Mapper.Map<T>(reader);
                //    if (tempt.Any())
                //    {
                //        t = tempt.First();
                //    }
                //}
                //else
                //{
                //    if (reader.Read())
                //    {
                //        t = DataUtils.Create<T>();
                //        t.SetPropertyValues(reader);
                //    }
                //}
                #endregion
                reader.Close();
            }

            setCache<T>(t, cacheKey);
            //2015-09-08
            if (t != null)
            {
                t.ClearModifyFields();
            }
            return t;
        }

        #endregion

        #region Union

        /// <summary>
        /// Union
        /// </summary>
        /// <param name="fromSection"></param>
        /// <returns></returns>
        public new FromSection<T> Union(FromSection fromSection)
        {
            StringBuilder tname = new StringBuilder();

            tname.Append("(");

            tname.Append(this.SqlNoneOrderbyString);

            tname.Append(" UNION ");

            tname.Append(fromSection.SqlNoneOrderbyString);

            tname.Append(")");

            tname.Append(" ");

            tname.Append(EntityCache.GetTableName<T>());

            FromSection<T> tmpfromSection = new FromSection<T>(this.database);
            tmpfromSection.tableName = tname.ToString();

            tmpfromSection.parameters.AddRange(this.Parameters);
            tmpfromSection.parameters.AddRange(fromSection.Parameters);

            return tmpfromSection;
        }

        /// <summary>
        /// Union All
        /// </summary>
        /// <param name="fromSection"></param>
        /// <returns></returns>
        public new FromSection<T> UnionAll(FromSection fromSection)
        {
            StringBuilder tname = new StringBuilder();

            tname.Append("(");

            tname.Append(this.SqlNoneOrderbyString);

            tname.Append(" UNION ALL ");

            tname.Append(fromSection.SqlNoneOrderbyString);

            tname.Append(")");

            tname.Append(" ");

            tname.Append(EntityCache.GetTableName<T>());

            FromSection<T> tmpfromSection = new FromSection<T>(this.database);
            tmpfromSection.tableName = tname.ToString();

            tmpfromSection.parameters.AddRange(this.Parameters);
            tmpfromSection.parameters.AddRange(fromSection.Parameters);

            return tmpfromSection;
        }

        #endregion

    }

    /// <summary>
    /// 查询
    /// </summary>
    public class FromSection
    {
        #region 变量

        protected WhereClip where = WhereClip.All;
        protected WhereClip havingWhere = WhereClip.All;
        protected OrderByClip orderBy = OrderByClip.None;
        protected GroupByClip groupBy = GroupByClip.None;
        protected string tableName;
        protected List<Parameter> parameters = new List<Parameter>();
        protected List<Field> fields = new List<Field>();
        protected DbProvider dbProvider;
        protected Dictionary<string, KeyValuePair<string, WhereClip>> joins = new Dictionary<string, KeyValuePair<string, WhereClip>>();
        protected Database database;
        protected string distinctString;
        protected string prefixString;

        /// <summary>
        /// 开始项
        /// </summary>
        protected int startIndex;
        /// <summary>
        /// 结束项
        /// </summary>
        protected int endIndex;

        /// <summary>
        /// 缓存超时时间
        /// </summary>
        protected int? timeout;

        /// <summary>
        /// 缓存依赖
        /// </summary>
        protected CacheDependency cacheDep = null;

        /// <summary>
        ///
        /// </summary>
        protected string typeTableName;

        /// <summary>
        /// 是否重新加载
        /// </summary>
        protected bool isRefresh = false;

        /// <summary>
        /// 是否已经执行过分页
        /// </summary>
        protected bool isPageFromSection = false;

        /// <summary>
        /// 事务   -- 查询
        /// </summary>
        protected DbTransaction trans;
        #endregion

        #region 属性
        //2015-08-12恢复注释
        /// <summary>
        /// DbProvider。
        /// </summary>
        public DbProvider DbProvider
        {
            get { return dbProvider; }
        }
        //2015-08-12新增
        /// <summary>
        /// DbProvider。
        /// </summary>
        public Database Database
        {
            get { return database; }
        }
        /// <summary>
        /// 设置 distinct
        /// </summary>
        internal string DistinctString
        {
            set
            {
                distinctString = value;
            }
        }

        /// <summary>
        /// 前置值如 Top N
        /// </summary>
        internal string PrefixString
        {
            set
            {
                prefixString = value;
            }
        }

        private string limitString;
        /// <summary>
        /// limit
        /// </summary>
        public string LimitString
        {
            set
            {

                limitString = value;
            }
        }

        /// <summary>
        /// 记录数sql语句 count
        /// </summary>
        public string CountSqlString
        {
            get
            {
                StringBuilder sql = new StringBuilder();

                if (GroupByClip.IsNullOrEmpty(groupBy) && string.IsNullOrEmpty(distinctString))
                {
                    sql.Append(" SELECT count(*) as r_cnt FROM ");
                    sql.Append(FromString);
                    if (!WhereClip.IsNullOrEmpty(where))
                    {
                        sql.Append(where.WhereString);
                    }
                }
                else
                {

                    sql.Append("SELECT count(*) as r_cnt FROM (");

                    sql.Append(SqlNoneOrderbyString);

                    sql.Append(") tmp__table");
                }

                return sql.ToString();
            }
        }

        /// <summary>
        /// 没有没有排序字段
        /// </summary>
        internal string SqlNoneOrderbyString
        {
            get
            {
                StringBuilder sql = new StringBuilder();

                sql.Append(" SELECT ");
                sql.Append(distinctString);
                sql.Append(" ");
                sql.Append(prefixString);
                sql.Append(" ");
                sql.Append(ColumnsString);
                sql.Append(" FROM ");
                sql.Append(FromString);
                sql.Append(" ");

                if (!WhereClip.IsNullOrEmpty(where))
                {
                    sql.Append(where.WhereString);
                }
                if (!GroupByClip.IsNullOrEmpty(groupBy))
                {
                    sql.Append(GroupByString);
                    if (!WhereClip.IsNullOrEmpty(havingWhere))
                    {
                        sql.Append(" HAVING ");
                        sql.Append(havingWhere.ToString());
                    }
                }
                return sql.ToString();
            }
        }

        /// <summary>
        ///
        /// </summary>
        internal string FromString
        {
            get
            {
                StringBuilder fromstring = new StringBuilder();

                //处理ACCESS 的多表联合查询
                if (database.DbProvider is MsAccess.MsAccessProvider)
                {
                    fromstring.Append('(', joins.Count);
                    fromstring.Append(tableName);
                    foreach (KeyValuePair<string, KeyValuePair<string, WhereClip>> kv in joins)
                    {
                        fromstring.Append(" ");
                        fromstring.Append(kv.Value.Key);
                        fromstring.Append(" ");
                        fromstring.Append(kv.Key);
                        fromstring.Append(" ON ");
                        fromstring.Append(kv.Value.Value.ToString());
                        fromstring.Append(")");
                    }

                }
                else
                {
                    fromstring.Append(tableName);
                    foreach (KeyValuePair<string, KeyValuePair<string, WhereClip>> kv in joins)
                    {
                        fromstring.Append(" ");
                        fromstring.Append(kv.Value.Key);
                        fromstring.Append(" ");
                        fromstring.Append(kv.Key);
                        fromstring.Append(" ON ");
                        fromstring.Append(kv.Value.Value.ToString());
                    }
                }

                return fromstring.ToString();
            }

        }

        /// <summary>
        /// 连接信息
        /// </summary>
        internal Dictionary<string, KeyValuePair<string, WhereClip>> Joins
        {
            get
            {
                return joins;
            }
            set
            {
                joins = value;
            }
        }

        /// <summary>
        /// 获取 sql语句
        /// </summary>
        public string SqlString
        {
            get
            {
                StringBuilder sql = new StringBuilder();

                sql.Append(" SELECT ");
                sql.Append(distinctString);
                sql.Append(" ");
                sql.Append(prefixString);
                sql.Append(" ");
                sql.Append(ColumnsString);
                sql.Append(" FROM ");
                sql.Append(FromString);
                sql.Append(" ");

                if (!WhereClip.IsNullOrEmpty(where))
                {
                    sql.Append(where.WhereString);
                }
                if (!GroupByClip.IsNullOrEmpty(groupBy))
                {
                    sql.Append(GroupByString);
                    if (!WhereClip.IsNullOrEmpty(havingWhere))
                    {
                        sql.Append(" HAVING ");
                        sql.Append(havingWhere.ToString());
                    }
                }

                sql.Append(OrderByString);
                sql.Append(" ");
                sql.Append(limitString);
                return sql.ToString();
            }
        }

        /// <summary>
        /// 返回  表名
        /// </summary>
        public string TableName
        {
            get
            {
                return tableName;
            }
            internal set
            {
                tableName = value;

                this.joins = new Dictionary<string, KeyValuePair<string, WhereClip>>();
            }
        }

        /// <summary>
        /// 返回  排序
        /// </summary>
        public OrderByClip OrderByClip
        {
            get
            {
                return orderBy;
            }
            internal set
            {
                orderBy = value;
            }
        }

        /// <summary>
        /// 返回排序字符串  例如:orderby id desc
        /// </summary>
        public string OrderByString
        {
            get
            {
                if (OrderByClip.IsNullOrEmpty(orderBy))
                    return string.Empty;

                if (tableName.IndexOf('(') >= 0 || tableName.IndexOf(')') >= 0 || tableName.IndexOf(" FROM ", StringComparison.OrdinalIgnoreCase) >= 0 || tableName.IndexOf(" AS ", StringComparison.OrdinalIgnoreCase) >= 0)
                    return orderBy.RemovePrefixTableName().OrderByString;
                return orderBy.OrderByString;
            }
        }

        /// <summary>
        /// 返回 分组
        /// </summary>
        public GroupByClip GroupByClip
        {
            get
            {
                return groupBy;
            }
            internal set
            {
                groupBy = value;
            }
        }

        /// <summary>
        /// 返回排序字符串 例如:group by id
        /// </summary>
        public string GroupByString
        {
            get
            {
                if (GroupByClip.IsNullOrEmpty(groupBy))
                    return string.Empty;
                if (tableName.IndexOf('(') >= 0 || tableName.IndexOf(')') >= 0 || tableName.IndexOf(" FROM ", StringComparison.OrdinalIgnoreCase) >= 0 || tableName.IndexOf(" AS ", StringComparison.OrdinalIgnoreCase) >= 0)
                    return groupBy.RemovePrefixTableName().GroupByString;
                return groupBy.GroupByString;
            }
        }

        /// <summary>
        /// 返回 条件
        /// </summary>
        public WhereClip WhereClip
        {
            get
            {
                return where;
            }
        }

        /// <summary>
        /// 返回 参数  (包含where 和 from)
        /// </summary>
        public List<Parameter> Parameters
        {
            get
            {
                List<Parameter> ps = new List<Parameter>();

                if (!WhereClip.IsNullOrEmpty(where))
                    ps.AddRange(where.Parameters);

                //处理groupby的having
                if (!GroupByClip.IsNullOrEmpty(groupBy) && !WhereClip.IsNullOrEmpty(havingWhere))
                    ps.AddRange(havingWhere.Parameters);

                ps.AddRange(parameters);

                return ps;
            }
            internal set
            {
                this.parameters = value;
            }

        }

        /// <summary>
        /// 返回  选择列
        /// </summary>
        public string ColumnsString
        {
            get
            {
                if (fields.Count == 0)
                    return "*";

                StringBuilder columns = new StringBuilder();
                foreach (Field filed in fields)
                {
                    columns.Append(",");
                    columns.Append(filed.FullName);
                }

                return columns.ToString().Substring(1);
            }
        }

        /// <summary>
        /// 查询的字段
        /// </summary>
        public List<Field> Fields
        {
            get
            {
                return this.fields;
            }
        }

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="database"></param>
        /// <param name="tableName"></param>
        public FromSection(Database database, string tableName)
            : this(database, tableName, (DbTransaction)null)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="database"></param>
        /// <param name="tableName"></param>
        /// <param name="trans"></param>
        public FromSection(Database database, string tableName, DbTransaction trans)
        {
            Check.Require(database, "database", Check.NotNull);
            Check.Require(tableName, "tableName", Check.NotNullOrEmpty);

            this.trans = trans;
            this.dbProvider = database.DbProvider;
            this.database = database;
            this.tableName = tableName;
            this.typeTableName = tableName.Trim(dbProvider.LeftToken, dbProvider.RightToken);
        }

        #endregion

        #region 操作

        /// <summary>
        /// 是否开启缓存
        /// </summary>
        /// <returns></returns>
        protected bool isTurnonCache()
        {
            if (null == dbProvider.CacheConfig)
                return false;

            return dbProvider.CacheConfig.Enable;

        }

        /// <summary>
        /// 判断是否用户自定义缓存策略
        /// </summary>
        /// <returns></returns>
        protected bool isCustomerCache()
        {
            return (timeout.HasValue || null != cacheDep);
        }

        /// <summary>
        /// 设置缓存有效期  单位:秒
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public FromSection SetCacheTimeOut(int timeout)
        {
            this.timeout = timeout;
            return this;
        }

        /// <summary>
        /// 设置缓存依赖
        /// </summary>
        /// <param name="dep"></param>
        /// <returns></returns>
        public FromSection SetCacheDependency(CacheDependency dep)
        {
            this.cacheDep = dep;
            return this;
        }

        /// <summary>
        /// 重新加载
        /// </summary>
        /// <returns></returns>
        public FromSection Refresh()
        {
            isRefresh = true;
            return this;
        }

        /// <summary>
        /// whereclip
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection Where(WhereClip where)
        {
            //2015-09-08修改
            this.where = where;
            //this.where = this.where && where;
            return this;
        }

        /// <summary>
        /// groupby
        /// </summary>
        /// <param name="groupBy"></param>
        /// <returns></returns>
        public FromSection GroupBy(GroupByClip groupBy)
        {
            //2015-09-08修改
            this.groupBy = groupBy;
            //this.groupBy = this.groupBy && groupBy;
            return this;
        }

        /// <summary>
        /// having条件
        /// </summary>
        /// <param name="havingWhere"></param>
        /// <returns></returns>
        public FromSection Having(WhereClip havingWhere)
        {
            //2015-09-08修改
            this.havingWhere = havingWhere;
            //this.havingWhere = this.havingWhere && havingWhere;
            return this;
        }

        /// <summary>
        /// groupby
        /// </summary>
        /// <param name="fields"></param>
        /// <returns></returns>
        public FromSection GroupBy(params Field[] fields)
        {
            if (null != fields && fields.Length > 0)
            {
                GroupByClip tempgroupby = GroupByClip.None;
                foreach (Field f in fields)
                {
                    tempgroupby = tempgroupby && f.GroupBy;
                }
                //2015-09-08修改
                this.groupBy = tempgroupby;
                //this.groupBy = this.groupBy && tempgroupby;
            }
            return this;
        }

        /// <summary>
        /// orderby
        /// </summary>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        public FromSection OrderBy(OrderByClip orderBy)
        {
            //2015-09-08修改
            this.orderBy = orderBy;
            //this.orderBy = this.orderBy && orderBy;
            return this;
        }

        /// <summary>
        /// orderby
        /// </summary>
        /// <param name="orderBys"></param>
        /// <returns></returns>
        public FromSection OrderBy(params OrderByClip[] orderBys)
        {
            if (null != orderBys && orderBys.Length > 0)
            {
                OrderByClip temporderby = OrderByClip.None;
                foreach (OrderByClip ob in orderBys)
                {
                    temporderby = temporderby && ob;
                }
                //2015-09-08修改
                this.orderBy =temporderby;
                //this.orderBy = this.orderBy && temporderby;
            }
            return this;
        }

        /// <summary>
        /// select field
        /// </summary>
        /// <param name="fields"></param>
        /// <returns></returns>
        public FromSection Select(params Field[] fields)
        {
            //2015-09-08取消注释
            this.fields.Clear();
            return AddSelect(fields);
        }

        /// <summary>
        /// select sql
        /// </summary>
        /// <param name="fromSection"></param>
        /// <returns></returns>
        public FromSection AddSelect(FromSection fromSection)
        {
            return AddSelect(fromSection, null);
        }

        /// <summary>
        /// select sql
        /// </summary>
        /// <param name="fromSection"></param>
        /// <param name="aliasName">别名</param>
        /// <returns></returns>
        public FromSection AddSelect(FromSection fromSection, string aliasName)
        {
            if (null == fromSection)
                return this;

            Check.Require(fromSection.Fields.Count == 1 && !fromSection.Fields[0].PropertyName.Equals("*"), "fromSection's fields must be only one!");

            this.fields.Add(new Field(string.Concat("(", fromSection.SqlString, ")")).As(aliasName));

            this.parameters.AddRange(fromSection.Parameters);

            return this;
        }

        /// <summary>
        /// add select field
        /// </summary>
        /// <param name="fields"></param>
        /// <returns></returns>
        internal FromSection AddSelect(params Field[] fields)
        {
            if (null != fields && fields.Length > 0)
            {
                foreach (Field field in fields)
                {
                    Field f = this.fields.Find(delegate(Field fi) { return fi.Name.Equals(field.Name); });
                    if (Field.IsNullOrEmpty(f))
                        this.fields.Add(field);
                }
            }
            return this;
        }

        /// <summary>
        /// Distinct
        /// </summary>
        /// <returns></returns>
        public FromSection Distinct()
        {
            this.distinctString = " DISTINCT ";
            return this;
        }

        /// <summary>
        /// Top
        /// </summary>
        /// <param name="topCount"></param>
        /// <returns></returns>
        public FromSection Top(int topCount)
        {
            return From(1, topCount);
        }

        /// <summary>
        /// Page
        /// </summary>
        /// <param name="pageSize">每页数</param>
        /// <param name="pageIndex">第几页</param>
        /// <returns></returns>
        public FromSection Page(int pageSize, int pageIndex)
        {
            return From(pageSize * (pageIndex - 1) + 1, pageIndex * pageSize);
        }

        /// <summary>
        /// From startIndex to endIndex
        /// </summary>
        /// <param name="startIndex">开始记录数</param>
        /// <param name="endIndex">结束记录数</param>
        /// <returns></returns>
        public FromSection From(int startIndex, int endIndex)
        {
            this.startIndex = startIndex;
            this.endIndex = endIndex;

            isPageFromSection = false;

            return this;
        }

        /// <summary>
        /// 格式化sql语句
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="from"></param>
        /// <returns></returns>
        protected string formatSql(string sql, FromSection from)
        {
            string tempSql = DataUtils.FormatSQL(sql, from.dbProvider.LeftToken, from.dbProvider.RightToken);
            List<Parameter> listPara = from.Parameters;
            foreach (Parameter p in listPara)
            {
                tempSql = tempSql.Replace(p.ParameterName, p.ParameterValue == null ? string.Empty : p.ParameterValue.ToString());
            }
            return tempSql;
        }

        #endregion

        #region 查询

        /// <summary>
        /// 获取记录数
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            //FromSection from;

            //if (!isPageFromSection)
            //    from = getPagedFromSection();
            //else
            //    from = this;

            return Count(getPagedFromSection());
        }

        /// <summary>
        /// 获取记录数(内部使用)
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        internal int Count(FromSection from)
        {
            string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "COUNT", "|", formatSql(from.CountSqlString, from));

            object cacheValue = getCache(cacheKey);
            if (null != cacheValue)
            {
                return (int)cacheValue;
            }

            DbCommand dbCommand = database.GetSqlStringCommand(from.CountSqlString);
            database.AddCommandParameter(dbCommand, from.Parameters.ToArray());
            int returnValue;
            if (trans == null)
                returnValue = DataUtils.ConvertValue<int>(database.ExecuteScalar(dbCommand));
            else
                returnValue = DataUtils.ConvertValue<int>(database.ExecuteScalar(dbCommand, trans));

            setCache<int>(returnValue, cacheKey);

            return returnValue;
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        protected object getCache(string cacheKey)
        {
            if (isRefresh)
                return null;

            object cacheValue = Cache.Default.GetCache(cacheKey);

            //if (null != cacheValue && isCustomerCache())
            //{
            //    Cache.Default.AddCacheDependency(cacheKey, cacheValue, timeout.HasValue ? timeout.Value : 0, cacheDep);
            //}

            return cacheValue;
        }

        /// <summary>
        /// 保存信息
        /// </summary>
        /// <param name="value"></param>
        /// <param name="cacheKey"></param>
        protected void setCache<T>(T value, string cacheKey)
        {
            if (isCustomerCache())
                Cache.Default.AddCacheDependency(cacheKey, value, timeout.HasValue ? timeout.Value : 0, cacheDep);
            else
            {
                if (isTurnonCache())
                {
                    string entityCacheKey = string.Concat(dbProvider.ConnectionStringsName, typeTableName);
                    if (dbProvider.EntitiesCache.ContainsKey(entityCacheKey))
                    {
                        int? temptimeOut = dbProvider.EntitiesCache[entityCacheKey].TimeOut;
                        if (temptimeOut.HasValue)
                        {
                            Cache.Default.AddCacheSlidingExpiration(cacheKey, value, temptimeOut.Value);
                        }
                        else
                        {
                            Cache.Default.AddCacheDependency(cacheKey, value, 0, new CacheDependency(dbProvider.EntitiesCache[entityCacheKey].FilePath));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// To DataSet
        /// </summary>
        /// <returns></returns>
        public DataSet ToDataSet()
        {
            FromSection from = getPagedFromSection();
            string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "DataSet", "|", formatSql(from.SqlString, from));
            object cacheValue = getCache(cacheKey);
            if (null != cacheValue)
            {
                return (DataSet)cacheValue;
            }

            DataSet ds;
            if (trans == null)
                ds = database.ExecuteDataSet(createDbCommand(from));
            else
                ds = database.ExecuteDataSet(createDbCommand(from), trans);

            setCache<DataSet>(ds, cacheKey);

            return ds;
        }

        /// <summary>
        /// 获取分页过的FromSection
        /// </summary>
        /// <returns></returns>
        internal FromSection getPagedFromSection()
        {
            if (startIndex > 0 && endIndex > 0 && !isPageFromSection)
            {
                isPageFromSection = true;
                return dbProvider.CreatePageFromSection(this, startIndex, endIndex);
            }
            else
            {
                return this;
            }
        }

        /// <summary>
        /// 创建  查询的DbCommand
        /// </summary>
        /// <returns></returns>
        protected DbCommand createDbCommand(FromSection from)
        {
            DbCommand dbCommand = database.GetSqlStringCommand(from.SqlString);
            database.AddCommandParameter(dbCommand, from.Parameters.ToArray());
            return dbCommand;
        }

        /// <summary>
        /// To DataReader
        /// </summary>
        /// <returns></returns>
        public IDataReader ToDataReader()
        {
            return ToDataReader(getPagedFromSection());
        }

        /// <summary>
        ///  To DataReader
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        protected IDataReader ToDataReader(FromSection from)
        {
            if (trans == null)
                return database.ExecuteReader(createDbCommand(from));
            else
                return database.ExecuteReader(createDbCommand(from), trans);
        }

        /// <summary>
        /// To DataTable
        /// </summary>
        /// <returns></returns>
        public DataTable ToDataTable()
        {
            return this.ToDataSet().Tables[0];
        }

        /// <summary>
        /// To Scalar
        /// </summary>
        /// <returns></returns>
        public object ToScalar()
        {
            Check.Require(this.fields.Count == 1, "fields must be one!");
            Check.Require(!this.fields[0].PropertyName.Trim().Equals("*"), "fields cound not be * !");

            FromSection from = getPagedFromSection();
            string cacheKey = string.Concat(dbProvider.ConnectionStringsName, "Scalar", "|", formatSql(from.SqlString, from));
            object cacheValue = getCache(cacheKey);
            if (null != cacheValue)
            {
                return cacheValue;
            }

            object returnValue;

            if (trans == null)
                returnValue = database.ExecuteScalar(createDbCommand(from));
            else
                returnValue = database.ExecuteScalar(createDbCommand(from), trans);

            setCache<object>(returnValue, cacheKey);

            return returnValue;

        }

        /// <summary>
        /// To Scalar
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        public TResult ToScalar<TResult>()
        {
            return DataUtils.ConvertValue<TResult>(this.ToScalar());
        }

        #endregion

        #region 连接 join

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="where"></param>
        /// <param name="joinType"></param>
        /// <returns></returns>
        protected FromSection join(string tableName, WhereClip where, JoinType joinType)
        {
            if (string.IsNullOrEmpty(tableName) || WhereClip.IsNullOrEmpty(where))
                return this;

            tableName = dbProvider.BuildTableName(tableName);

            if (!joins.ContainsKey(tableName))
            {
                string joinString = string.Empty;
                switch (joinType)
                {
                    case JoinType.InnerJoin:
                        joinString = "INNER JOIN";
                        break;
                    case JoinType.LeftJoin:
                        joinString = "LEFT OUTER JOIN";
                        break;
                    case JoinType.RightJoin:
                        joinString = "RIGHT OUTER JOIN";
                        break;
                    case JoinType.CrossJoin:
                        joinString = "CROSS JOIN";
                        break;
                    case JoinType.FullJoin:
                        joinString = "FULL OUTER JOIN";
                        break;
                    default:
                        joinString = "INNER JOIN";
                        break;
                }

                joins.Add(tableName, new KeyValuePair<string, WhereClip>(joinString, where));

                if (where.Parameters.Count > 0)
                    parameters.AddRange(where.Parameters);
            }

            return this;
        }

        /// <summary>
        /// Inner Join
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection InnerJoin(string tableName, WhereClip where)
        {
            return join(tableName, where, JoinType.InnerJoin);
        }

        /// <summary>
        /// Left Join
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection LeftJoin(string tableName, WhereClip where)
        {
            return join(tableName, where, JoinType.LeftJoin);
        }

        /// <summary>
        /// Right Join
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection RightJoin(string tableName, WhereClip where)
        {
            return join(tableName, where, JoinType.RightJoin);
        }

        /// <summary>
        /// Cross Join
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection CrossJoin(string tableName, WhereClip where)
        {
            return join(tableName, where, JoinType.CrossJoin);
        }

        /// <summary>
        /// Full Join
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public FromSection FullJoin(string tableName, WhereClip where)
        {
            return join(tableName, where, JoinType.FullJoin);
        }

        #endregion

        #region Union

        /// <summary>
        /// Union
        /// </summary>
        /// <param name="fromSection"></param>
        /// <returns></returns>
        public FromSection Union(FromSection fromSection)
        {
            StringBuilder tname = new StringBuilder();

            tname.Append("(");

            tname.Append(this.SqlNoneOrderbyString);

            tname.Append(" UNION ");

            tname.Append(fromSection.SqlNoneOrderbyString);

            tname.Append(") tempuniontable ");

            FromSection tmpfromSection = new FromSection(this.database, tname.ToString());
            tmpfromSection.typeTableName = this.typeTableName;
            tmpfromSection.timeout = this.timeout;
            tmpfromSection.cacheDep = this.cacheDep;
            tmpfromSection.isRefresh = this.isRefresh;

            tmpfromSection.parameters.AddRange(this.Parameters);
            tmpfromSection.parameters.AddRange(fromSection.Parameters);

            return tmpfromSection;
        }

        /// <summary>
        /// Union All
        /// </summary>
        /// <param name="fromSection"></param>
        /// <returns></returns>
        public FromSection UnionAll(FromSection fromSection)
        {
            StringBuilder tname = new StringBuilder();

            tname.Append("(");

            tname.Append(this.SqlNoneOrderbyString);

            tname.Append(" UNION ALL ");

            tname.Append(fromSection.SqlNoneOrderbyString);

            tname.Append(") tempuniontable ");

            FromSection tmpfromSection = new FromSection(this.database, tname.ToString());
            tmpfromSection.typeTableName = this.typeTableName;
            tmpfromSection.timeout = this.timeout;
            tmpfromSection.cacheDep = this.cacheDep;
            tmpfromSection.isRefresh = this.isRefresh;

            tmpfromSection.parameters.AddRange(this.Parameters);
            tmpfromSection.parameters.AddRange(fromSection.Parameters);

            return tmpfromSection;
        }

        #endregion
    }
}


text:
'use strict';
const common = require('../common');
const http = require('http');
const assert = require('assert');

{
  // abort

  const server = http.createServer(common.mustCall((req, res) => {
    res.end('Hello');
  }));

  server.listen(0, common.mustCall(() => {
    const options = { port: server.address().port };
    const req = http.get(options, common.mustCall((res) => {
      res.on('data', (data) => {
        req.abort();
        assert.strictEqual(req.aborted, true);
        assert.strictEqual(req.destroyed, true);
        server.close();
      });
    }));
    req.on('error', common.mustNotCall());
    assert.strictEqual(req.aborted, false);
    assert.strictEqual(req.destroyed, false);
  }));
}

{
  // destroy + res

  const server = http.createServer(common.mustCall((req, res) => {
    res.end('Hello');
  }));

  server.listen(0, common.mustCall(() => {
    const options = { port: server.address().port };
    const req = http.get(options, common.mustCall((res) => {
      res.on('data', (data) => {
        req.destroy();
        assert.strictEqual(req.aborted, false);
        assert.strictEqual(req.destroyed, true);
        server.close();
      });
    }));
    req.on('error', common.mustNotCall());
    assert.strictEqual(req.aborted, false);
    assert.strictEqual(req.destroyed, false);
  }));
}

{
  // destroy

  const server = http.createServer(common.mustNotCall((req, res) => {
  }));

  server.listen(0, common.mustCall(() => {
    const options = { port: server.address().port };
    const req = http.get(options, common.mustNotCall());
    req.on('error', common.mustCall((err) => {
      assert.strictEqual(err.code, 'ECONNRESET');
      server.close();
    }));
    assert.strictEqual(req.aborted, false);
    assert.strictEqual(req.destroyed, false);
    req.destroy();
    assert.strictEqual(req.aborted, false);
    assert.strictEqual(req.destroyed, true);
  }));
}


text:
<?php

namespace SD\CalendarBundle\Controller;

use SD\UserBundle\Entity\User;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Translation\Translator;

/**
 * Class PrivateController
 */
class PrivateController extends SalesController
{
    protected $baseRoutePrefix = 'private';
    protected $baseTemplate = 'Private';

    /**
     * Renders template holder for calendar
     *
     * @return string
     */
    public function indexAction()
    {
        return $this->render('SDCalendarBundle::base.html.twig', array(
            'url' => $this->get('router')->generate('sd_calendar_private_message')
        ));
    }

    /**
     * Renders tasks
     *
     * @return string
     */
    public function taskAction()
    {
        $em = $this->getDoctrine()->getManager();
        $taskRepo = $em->getRepository('SDCalendarBundle:Task');
        $tasksDone = $taskRepo->
            getPersonalTaskDone($this->getUser()->getId(), 'personal');
        $tasksOpen = $taskRepo->
            getFivePersonalTaskOpen($this->getUser()->getId(), 'personal');
        $tasksCreated = $taskRepo->
            getFivePersonalTaskCreated($this->getUser()->getId(), 'personal');

        return $this->render('SDCalendarBundle:Task:tasks.html.twig', array(
            'tasksDone' => $tasksDone,
            'tasksOpen' => $tasksOpen,
            'tasksCreated' => $tasksCreated
        ));
    }

    /**
     * Renders done tasks
     *
     * @return string
     */
    public function tasksDoneAction()
    {
        $em = $this->getDoctrine()->getManager();
        $tasksDone = $em->getRepository('SDCalendarBundle:Task')->
            getPersonalTaskDone($this->getUser()->getId(), 'personal');

        return $this->render('SDCalendarBundle:Task:tasksDone.html.twig', array(
            'tasksDone' => $tasksDone
        ));
    }

    /**
     * Update task. Make it done/viewed
     *
     * @param Request $request
     *
     * @return Response
     */
    public function setDoneTaskAction(Request $request)
    {
        $id = $request->request->get('id');
        $em = $this->getDoctrine()->getManager();
        $task = $em->getRepository('SDCalendarBundle:Task')->find($id);
        $task->setIsDone(true);
        $em->persist($task);
        $em->flush();
        $return = array();
        $return['success'] = 1;

        return new Response(json_encode($return));
    }

    /**
     * Renders modal inner html for one task
     *
     * @param Request $request
     *
     * @return Response
     */
    public function oneTaskAjaxAction(Request $request)
    {
        $id = $request->request->get('id');
        $em = $this->getDoctrine()->getManager();
        $task = $em->getRepository('SDCalendarBundle:Task')->find($id);
        $userId = $this->getUser()->getId();
        $return = array();
        $return['html'] = $this->renderView('SDCalendarBundle:Task:taskModal.html.twig', array(
            'task' => $task,
            'userId' => $userId
        ));

        return new Response(json_encode($return));
    }

    /**
     * Returns events depending on userIds and userRoles
     *
     * @param int[]  $userIds
     * @param string $startTimestamp
     * @param string $endTimestamp
     *
     * @return mixed[]
     */
    public function getEventsByUserIds($userIds, $startTimestamp, $endTimestamp)
    {
        $em = $this->getDoctrine()->getManager();
        $user = $this->getUser();
        $events = array();
        /** @var Translator $translator */
        $translator = $this->container->get('translator');
        /** get handling */
        if ($user->hasRole('ROLE_SALES') || $this->getUser()->hasRole('ROLE_SALESADMIN')) {
            $session = $this->get('session');
            $managerForCalendar = $session->get('managerForCalendar', null);
            if ($managerForCalendar) {
                $userIds = array($managerForCalendar);
            }

            $projects = $em->getRepository('ListsProjectBundle:Project')->getLastMessages($userIds, $startTimestamp, $endTimestamp);

            foreach ($projects as $project) {
                $url = $this->generateUrl('lists_project_'.$project['project']->getDiscr().'_show', array(
                        'id' => $project['project']->getId()
                    ));
                $title = $project['nameType']. ' | '. $project['nameOrganization']. ' (' . $project['eventDatetime']->format('H:i').')';
                $cssClass = 'projectMessage';
                if ($project['eventDatetime'] < new \DateTime()) {
                    $cssClass .= ' sd-event-prev';
                    if ($project['project']->getIsClosed() && $project['project']->getDatetimeClosed() < $project['eventDatetime']) {
                        $cssClass .= ' sd-event-yellow';
                    } else {
                        $cssClass .= ' sd-event-red ';
                    }
                } else {
                    $cssClass .= ' sd-event-green';
                }
                $editable = true;
                if ($managerForCalendar) {
                    $editable = false;
                }
                $events[] = array(
                    'hover_title' => '',
                    'editable' => $editable,
                    'messageUrlUpdate' => $this->generateUrl('lists_project_message_update', array( 'id' => $project['messageId'])),
                    'title' => $title,
                    'start' => $project['eventDatetime']->format('Y-m-d H:i:s'),
                    'end' => $project['eventDatetime']->format('Y-m-d H:i:s'),
                    'url' => $url,
                    'className' => $cssClass,
                    'allDay' => false,
                );
            }
        }

        /** get article */
        $decision = $em->getRepository('ListsArticleBundle:Article')
                ->getDecisionForCalendar($this->getUser()->getId());
        foreach ($decision as $val) {
            $events[] = array(
                'hover_title' => '',
                'title' => $val['title']. ' ('. $val['dateUnpublick']->format('H:i'). ')',
                'start' => $val['dateUnpublick']->format('Y-m-d H:i:s'),
                'url' => $this->generateUrl('list_article_vote_decision_show', array(
                            'id' => $val['id']
                        )),
                'className' => 'sd-event-next'
            );
        }

        /** get task */
        $task = $em->getRepository('SDCalendarBundle:Task')->getPersonalTask($this->getUser()->getId(), 'personal');
        foreach ($task as $val) {
            $events[] = array(
                'hover_title' => '',
                'modal' => 'on',
                'data_id' => $val['id'],
                'title' => $val['title']. ' ('. $val['startDateTime']->format('H:i'). ')',
                'start' => $val['startDateTime']->format('Y-m-d H:i:s'),
                'end' => $val['stopDateTime']->format('Y-m-d H:i:s'),
                'allDay' => false,
                'url' => '#create_task'
                );
        }
        /** @var User[] $users get birthdays */
        $users = $em->getRepository('SDUserBundle:User')
                ->getBirthdaysForCalendar($startTimestamp, $endTimestamp);
        foreach ($users as $user) {
            $fullName = $user->getFullname();
            $events[] = array(
                'hover_title' => '',
                'editable' => false,
                'title' => $translator->trans('BD', array(), 'SDDashboardBundle').' '. $fullName,
                'start' => date('Y').'-'.$user->getBirthday()->format('m-d'),
                'end' => date('Y').'-'.$user->getBirthday()->format('m-d'),
                'allDay' => true,
                'url' => $this->generateUrl('sd_user_show', array(
                    'id' => $user->getId()
                )),
                );
        }
        /** @var Holiday[] $holidays */
        $holidays = $em->getRepository('SDCalendarBundle:Holiday')
                ->getListForDate($startTimestamp, $endTimestamp);
        foreach ($holidays as $holiday) {
            $name = $holiday->getName();
            $events[] = array(
                'hover_title' => '',
                'title' => $name,
                'start' => date('Y').'-'.$holiday->getDate()->format('m').'-'.$holiday->getDate()->format('d'),
                'end' => date('Y').'-'.$holiday->getDate()->format('m').'-'.$holiday->getDate()->format('d'),
                'allDay' => true
                );
        }
        //  ProjectStateTender
        $gosTenders = $em->getRepository('ListsProjectBundle:ProjectStateTender')
                ->getListForDate($startTimestamp, $endTimestamp, $this->getUser());
        foreach ($gosTenders as $tender) {
            $name = $translator->trans('Tender', array(), 'ListsProjectBundle').' | '. $tender
                ->getProject()->getOrganization()->getCity();
            $events[] = array(
                'hover_title' => '',
                'title' => $name,
                'url' => $this->generateUrl('lists_project_state_tender_show', array(
                        'id' => $tender->getId()
                    )),
                'start' => $tender->getDatetimeDeadline()->format('Y-m-d H:i'),
                'end' => $tender->getDatetimeDeadline()->format('Y-m-d H:i')
                );
        }

        //tasks
        $taskUserRoles = $em->getRepository('SDTaskBundle:TaskUserRole')
            ->findBy(array(
                'user' => $user
            ));
        $stageAccepted = $em->getRepository('SDTaskBundle:Stage')
            ->findOneBy(array(
                'name' => 'accepted',
                'model' => 'task_end_date'
            ));
        $rolePerformerController = $em->getRepository('SDTaskBundle:Role')
            ->findBy(array(
                'name' => array('performer', 'controller'),
                'model' => 'task'
            ));
        //var_dump(count($taskUserRoles));die();
        foreach ($taskUserRoles as $taskUserRole) {
            $task = $taskUserRole->getTask();
            $stage = $task->getStage();
            $role = $taskUserRole->getRole();
            if ($stage == 'closed' || $stage == 'undone' || $stage == 'done') {
                continue;
            }
            if ($stage == 'matching' && ($role == 'performer' || $role='controller')) {
                continue;
            }
            if ($role == 'author') {
                $userTask = $taskUserRole->getUser();
                $otherTaskUserRoles = $em->getRepository('SDTaskBundle:TaskUserRole')
                    ->findBy(array(
                        'user' => $userTask,
                        'task' => $task,
                        'role' => $rolePerformerController
                    ));
                if ($otherTaskUserRoles) {
                    continue;
                }
            }
            $endDate = $em->getRepository('SDTaskBundle:TaskEndDate')
                ->findOneBy(array(
                    'task' => $task,
                    'stage' => $stageAccepted
                ));

            $events[] = array(
                'hover_title' => '',
                'title' => $taskUserRole->getTask()->getTitle(),
                'start' => $endDate->getEndDateTime()->format('Y-m-d H:i'),
                'end' => $endDate->getEndDateTime()->format('Y-m-d H:i'),
                'url' => $this->generateUrl('sd_task_homepage').'?id='.$taskUserRole->getId()
                //'allDay' => true
            );
        }

        return $events;
    }
}


text:
* Greenworks compiled for NW.js v0.12.1 with Steamworks SDK 1.34
* Upgrade nan to v2 to support iojs v3.
* Add achievements and authentication APIs and support listening steam events:
  * greenworks.getNumberOfAchievements
  * greenworks.getAchievement
  * greenworks.clearAchievement
  * greenworks.getAchievementNames
  * greenworks.getAuthSessionTicket
  * greenworks.getEncryptedAppTicket
  * greenworks.cancelAuthTicket
  * greenworks.activateGameOverlayToWebPage
  * greenworks.on('game-overlay-activated')
  * greenworks.on('steam-servers-connected')
  * greenworks.on('steam-servers-disconnected')
  * greenworks.on('steam-servers-connect-failure')
  * greenworks.on('steam-shutdown')

## 2015.03.26 v0.4.1 stable

* Upgrade nan module to support node v0.12 as well as iojs
* Greenworks complied for NW.js(formerly node-webkit) v0.12.0 with Steamworks SDK 1.30

## 2014.10.24 v0.4.0 stable

* Greenworks complied for node-webkit v0.8.6 and v0.11.2 with Steamworks SDK 1.30
* Add activateGameOverlay and IsGameOverlayEnabled APIs
* Fix: a segment fault when zipOpenNewFileInZip4_64 fails

## 2014.10.24 v0.3.0 stable

* Greenworks complied for node-webkit v0.8.6 and v0.10.5 with Steamworks SDK 1.30
* All Greenworks APIs(cloud APIs, workshop APIs, utils APIs, Steam Info APIs) are totally rewritten with [NAN](https://github.com/rvagg/nan) module, supports node v0.10.X and node v0.11.X

## 2014.10.10 v0.3.0-alpha

* Greenworks APIs compiled for node-webkit v0.8.6 and v0.10.5
* Greenworks core methods(see below) are rewritten with `Nan` module, supports node v0.10.X and v0.11.X
  * initAPI
  * getSteamId
  * saveTextToFile
  * readTextFromFile
  * isCloudEnabled
  * isCloudEnabledForUser
  * enableCloud
  * getCloudQuota
  * activateAchievement
  * getCurrentGameLanguage
  * getCurrentUILanguage
  * getCurrentGameInstallDir
  * getNumberOfPlayers
  * fileShare
  * Utils.move

## 2014.08.11 v0.2.0

* Greenworks compiled for node-webkit v0.8.6 with Steamworks SDK 1.30
* Add Steamworks workshop APIs, such as synchronization, download, publish, update, unsubscribe or getting the Steam ID
* Add Utils APIs, like zip, unzip, write to console and/or log file

## 2013.12.02 v0.1.0

* Greenworks compiled for node-webkit v0.8.4 with Steamworks SDK 1.30


text:
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

using Microsoft.Win32.SafeHandles;
using System;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;

#pragma warning disable CS1998  // async no await

namespace Thrift.Transport.Server
{
    [Obsolete("NamedPipeClientFlags is deprecated, use NamedPipeServerFlags instead.")]
    [Flags]
    public enum NamedPipeClientFlags {  // bad name
        None = 0x00,
        OnlyLocalClients = 0x01
    };

    [Flags]
    public enum NamedPipeServerFlags
    {
        None = 0x00,
        OnlyLocalClients = 0x01,
    };

    // ReSharper disable once InconsistentNaming
    public class TNamedPipeServerTransport : TServerTransport
    {
        // to manage incoming connections, we set up a task for each stream to listen on
        private struct TaskStreamPair
        {
            public NamedPipeServerStream Stream;
            public Task Task;

            public TaskStreamPair(NamedPipeServerStream stream, Task task)
            {
                Stream = stream;
                Task = task;
            }
        }

        /// <summary>
        ///     This is the address of the Pipe on the localhost.
        /// </summary>
        private readonly string _pipeAddress;
        private bool _asyncMode = true;
        private volatile bool _isPending = true;
        private readonly List<TaskStreamPair> _streams = new List<TaskStreamPair>();
        private readonly bool _onlyLocalClients = false;  // compatibility default
        private readonly byte _numListenPipes = 1;  // compatibility default

        public TNamedPipeServerTransport(string pipeAddress, TConfiguration config, NamedPipeServerFlags flags, int numListenPipes)
            : base(config)
        {
            if ((numListenPipes < 1) || (numListenPipes > 254))
                throw new ArgumentOutOfRangeException(nameof(numListenPipes), "Value must be in the range of [1..254]");

            _pipeAddress = pipeAddress;
            _onlyLocalClients = flags.HasFlag(NamedPipeServerFlags.OnlyLocalClients);
            _numListenPipes = (byte)numListenPipes;
        }

        [Obsolete("NamedPipeClientFlags is deprecated, use NamedPipeServerFlags instead.")]
        public TNamedPipeServerTransport(string pipeAddress, TConfiguration config, NamedPipeClientFlags flags, int numListenPipes = 1)
            : base(config)
        {
            if ((numListenPipes < 1) || (numListenPipes > 254))
                throw new ArgumentOutOfRangeException(nameof(numListenPipes), "Value must be in the range of [1..254]");

            _pipeAddress = pipeAddress;
            _onlyLocalClients = flags.HasFlag(NamedPipeClientFlags.OnlyLocalClients);
            _numListenPipes = (byte)numListenPipes;
        }

        public override bool IsOpen() {
            return true;
        }

        public override void Listen()
        {
            // nothing to do here
        }

        private static void Close(NamedPipeServerStream pipe)
        {
            if (pipe != null)
            {
                try
                {
                    if (pipe.IsConnected)
                        pipe.Disconnect();
                }
                finally
                {
                    pipe.Dispose();
                }
            }
        }

        public override void Close()
        {
            try
            {
                if (_streams != null)
                {
                    while(_streams.Count > 0)
                    {
                        Close(_streams[0].Stream);
                        _streams.RemoveAt(0);
                    }
                }
            }
            finally
            {
                _streams.Clear();
                _isPending = false;
            }
        }

        public override bool IsClientPending()
        {
            return _isPending;
        }

        private void EnsurePipeInstances()
        {
            // set up a pool for accepting multiple calls when in multithread mode
            // once connected, we hand that stream over to the processor and create a fresh one
            try
            {
                while (_streams.Count < _numListenPipes)
                    _streams.Add(CreatePipeInstance());
            }
            catch
            {
                // we might not be able to create all requested instances, e.g. due to some existing instances already processing calls
                // if we have at least one pipe to listen on -> Good Enough(tm)
                if (_streams.Count < 1)
                    throw;  // no pipes is really bad
            }
        }

        private TaskStreamPair CreatePipeInstance()
        {
            const PipeDirection direction = PipeDirection.InOut;
            const int maxconn = NamedPipeServerStream.MaxAllowedServerInstances;
            const PipeTransmissionMode mode = PipeTransmissionMode.Byte;
            const int inbuf = 4096;
            const int outbuf = 4096;
            var options = _asyncMode ? PipeOptions.Asynchronous : PipeOptions.None;

            // TODO: "CreatePipeNative" ist only a workaround, and there are have basically two possible outcomes:
            // - once NamedPipeServerStream() gets a CTOR that supports pipesec, remove CreatePipeNative()
            // - if 31190 gets resolved before, use _stream.SetAccessControl(pipesec) instead of CreatePipeNative()
            // EITHER WAY,
            // - if CreatePipeNative() finally gets removed, also remove "allow unsafe code" from the project settings

            NamedPipeServerStream instance;
            try
            {
                var handle = CreatePipeNative(_pipeAddress, inbuf, outbuf, _onlyLocalClients);
                if ((handle != null) && (!handle.IsInvalid))
                {
                    instance = new NamedPipeServerStream(PipeDirection.InOut, _asyncMode, false, handle);
                    handle = null; // we don't own it any longer
                }
                else
                {
                    handle?.Dispose();
                    instance = new NamedPipeServerStream(_pipeAddress, direction, maxconn, mode, options, inbuf, outbuf/*, pipesec*/);
                }
            }
            catch (NotImplementedException) // Mono still does not support async, fallback to sync
            {
                if (_asyncMode)
                {
                    options &= (~PipeOptions.Asynchronous);
                    instance = new NamedPipeServerStream(_pipeAddress, direction, maxconn, mode, options, inbuf, outbuf);
                    _asyncMode = false;
                }
                else
                {
                    throw;
                }
            }

            // the task gets added later
            return new TaskStreamPair( instance, null);
        }

        #region CreatePipeNative workaround

        [StructLayout(LayoutKind.Sequential)]
        internal class SECURITY_ATTRIBUTES
        {
            internal int nLength = 0;
            internal IntPtr lpSecurityDescriptor = IntPtr.Zero;
            internal int bInheritHandle = 0;
        }

        private const string Kernel32 = "kernel32.dll";

        [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
        internal static extern IntPtr CreateNamedPipe(
            string lpName, uint dwOpenMode, uint dwPipeMode,
            uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut,
            SECURITY_ATTRIBUTES pipeSecurityDescriptor
            );

        // Workaround: create the pipe via API call
        // we have to do it this way, since NamedPipeServerStream() for netstd still lacks a few CTORs and/or arguments
        // and _stream.SetAccessControl(pipesec); only keeps throwing ACCESS_DENIED errors at us
        // References:
        // - https://github.com/dotnet/corefx/issues/30170 (closed, continued in 31190)
        // - https://github.com/dotnet/corefx/issues/31190 System.IO.Pipes.AccessControl package does not work
        // - https://github.com/dotnet/corefx/issues/24040 NamedPipeServerStream: Provide support for WRITE_DAC
        // - https://github.com/dotnet/corefx/issues/34400 Have a mechanism for lower privileged user to connect to a privileged user's pipe
        private static SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf, bool OnlyLocalClients)
        {
            if (! RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                return null; // Windows only

            var pinningHandle = new GCHandle();
            try
            {
                // owner gets full access, everyone else read/write
                var pipesec = new PipeSecurity();
                using (var currentIdentity = WindowsIdentity.GetCurrent())
                {
                    var sidOwner = currentIdentity.Owner;
                    var sidWorld = new SecurityIdentifier(WellKnownSidType.WorldSid, null);

                    pipesec.SetOwner(sidOwner);
                    pipesec.AddAccessRule(new PipeAccessRule(sidOwner, PipeAccessRights.FullControl, AccessControlType.Allow));
                    pipesec.AddAccessRule(new PipeAccessRule(sidWorld, PipeAccessRights.ReadWrite, AccessControlType.Allow));
                }

                // create a security descriptor and assign it to the security attribs
                var secAttrs = new SECURITY_ATTRIBUTES();
                byte[] sdBytes = pipesec.GetSecurityDescriptorBinaryForm();
                pinningHandle = GCHandle.Alloc(sdBytes, GCHandleType.Pinned);
                unsafe {
                    fixed (byte* pSD = sdBytes) {
                        secAttrs.lpSecurityDescriptor = (IntPtr)pSD;
                    }
                }

                // a bunch of constants we will need shortly
                const uint PIPE_ACCESS_DUPLEX = 0x00000003;
                const uint FILE_FLAG_OVERLAPPED = 0x40000000;
                const uint WRITE_DAC = 0x00040000;
                const uint PIPE_TYPE_BYTE = 0x00000000;
                const uint PIPE_READMODE_BYTE = 0x00000000;
                const uint PIPE_UNLIMITED_INSTANCES = 255;
                const uint PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000;  // Connections from remote clients can be accepted and checked against the security descriptor for the pipe.
                const uint PIPE_REJECT_REMOTE_CLIENTS = 0x00000008;  // Connections from remote clients are automatically rejected.

                // any extra flags we want to add
                uint dwPipeModeXtra
                    = (OnlyLocalClients ? PIPE_REJECT_REMOTE_CLIENTS : PIPE_ACCEPT_REMOTE_CLIENTS)
                    ;

                // create the pipe via API call
                var rawHandle = CreateNamedPipe(
                    @"\\.\pipe\" + name,
                    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC,
                    PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | dwPipeModeXtra,
                    PIPE_UNLIMITED_INSTANCES, (uint)inbuf, (uint)outbuf,
                    5 * 1000,
                    secAttrs
                    );

                // make a SafePipeHandle() from it
                var handle = new SafePipeHandle(rawHandle, true);
                if (handle.IsInvalid)
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                // return it (to be packaged)
                return handle;
            }
            finally
            {
                if (pinningHandle.IsAllocated)
                    pinningHandle.Free();
            }
        }

        #endregion

        protected override async ValueTask<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken)
        {
            try
            {
                EnsurePipeInstances();

                // fill the list and wait for any task to be completed
                var tasks = new List<Task>();
                for (var i = 0; i < _streams.Count; ++i)
                {
                    if (_streams[i].Task == null)
                    {
                        var pair = _streams[i];
                        pair.Task = Task.Run(async () => await pair.Stream.WaitForConnectionAsync(cancellationToken), cancellationToken);
                        _streams[i] = pair;
                    }

                    tasks.Add(_streams[i].Task);
                }

                // there must be an exact mapping between task index and stream index
                Debug.Assert(_streams.Count == tasks.Count);
                var index = Task.WaitAny(tasks.ToArray(), cancellationToken);

                var trans = new ServerTransport(_streams[index].Stream, Configuration);
                _streams.RemoveAt(index); // pass stream ownership to ServerTransport

                return trans;
            }
            catch (TTransportException)
            {
                Close();
                throw;
            }
            catch (TaskCanceledException)
            {
                Close();
                throw;  // let it bubble up
            }
            catch (Exception e)
            {
                Close();
                throw new TTransportException(TTransportException.ExceptionType.NotOpen, e.Message);
            }
        }

        private class ServerTransport : TEndpointTransport
        {
            private NamedPipeServerStream PipeStream;

            public ServerTransport(NamedPipeServerStream stream, TConfiguration config)
                : base(config)
            {
                PipeStream = stream;
            }

            public override bool IsOpen => PipeStream != null && PipeStream.IsConnected;

            public override Task OpenAsync(CancellationToken cancellationToken)
            {
                cancellationToken.ThrowIfCancellationRequested();
                return Task.CompletedTask;
            }

            public override void Close()
            {
                if (PipeStream != null)
                {
                    if (PipeStream.IsConnected)
                        PipeStream.Disconnect();
                    PipeStream.Dispose();
                    PipeStream = null;
                }
            }

            public override async ValueTask<int> ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
            {
                if (PipeStream == null)
                {
                    throw new TTransportException(TTransportException.ExceptionType.NotOpen);
                }

                CheckReadBytesAvailable(length);
#if NETSTANDARD2_0
                var numBytes = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
#else
                var numBytes = await PipeStream.ReadAsync(buffer.AsMemory(offset, length), cancellationToken);
#endif
                CountConsumedMessageBytes(numBytes);
                return numBytes;
            }

            public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
            {
                if (PipeStream == null)
                {
                    throw new TTransportException(TTransportException.ExceptionType.NotOpen);
                }

                // if necessary, send the data in chunks
                // there's a system limit around 0x10000 bytes that we hit otherwise
                // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section."
                var nBytes = Math.Min(15 * 4096, length); // 16 would exceed the limit
                while (nBytes > 0)
                {
#if NET5_0_OR_GREATER
                    await PipeStream.WriteAsync(buffer.AsMemory(offset, nBytes), cancellationToken);
#else
                    await PipeStream.WriteAsync(buffer, offset, nBytes, cancellationToken);
#endif
                    offset += nBytes;
                    length -= nBytes;
                    nBytes = Math.Min(nBytes, length);
                }
            }

            public override async Task FlushAsync(CancellationToken cancellationToken)
            {
                await PipeStream.FlushAsync(cancellationToken);
                ResetConsumedMessageSize();
            }

            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    if (PipeStream != null)
                    {
                        if (PipeStream.IsConnected)
                            PipeStream.Disconnect();
                        PipeStream.Dispose();
                        PipeStream = null;
                    }
                }
            }
        }
    }
}