/* 2019.9.20.0 */

#if NET40 || NET461

using Apewer;
using Apewer.Source;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Text;

namespace Apewer.Source
{

    /// <summary>用于快速连接 Microsoft SQL Server 数据库的辅助。</summary>
    [Serializable]
    public class SqlServer : IDatabase, IDisposable
    {

        #region 变量定义。

        private Logger _logger = null;
        private SqlConnection _db = null;

        private Timeout _timeout;
        private string _connectionstring = "";
        private string _address = "";
        private string _store = "";
        private string _user = "";
        private string _pass = "";

        #endregion

        #region 构造函数。

        /// <summary>创建空参数的数据库连接实例。</summary>
        public SqlServer()
        {
            _timeout = Timeout.Default;
        }

        /// <summary>使用连接字符串创建数据库连接实例。</summary>
        public SqlServer(string connectionString)
        {
            _timeout = Timeout.Default;
            _connectionstring = connectionString ?? "";
        }

        /// <summary>使用连接凭据创建数据库连接实例。</summary>
        /// <param name="address">服务器地址。</param>
        /// <param name="store">数据库名称。</param>
        public SqlServer(string address, string store)
        {
            _timeout = Timeout.Default;
            _address = address ?? "";
            _store = store ?? "";
            UpdateConnectString();
        }

        /// <summary>使用连接凭据创建数据库连接实例。</summary>
        /// <param name="address">服务器地址。</param>
        /// <param name="store">数据库名称。</param>
        /// <param name="user">用户名。</param>
        /// <param name="pass">密码。</param>
        public SqlServer(string address, string store, string user, string pass)
        {
            _timeout = Timeout.Default;
            _address = address ?? "";
            _store = store ?? "";
            _user = user ?? "";
            _pass = pass ?? "";
            UpdateConnectString();
        }

        #endregion

        #region 实现接口。

        /// <summary>获取或设置日志记录。</summary>
        public Logger Logger { get { if (_logger == null) _logger = Logger.Default(this); return _logger; } }

        /// <summary>数据库是否已经连接。</summary>
        public bool Online
        {
            get
            {
                if (_db == null) return false;
                return (_db.State == ConnectionState.Open);
            }
        }

        /// <summary>连接数据库,若未连接则尝试连接,获取连接成功的状态。</summary>
        public bool Connect()
        {
            if (_db == null)
            {
                _db = new SqlConnection();
                _db.ConnectionString = ConnectionString;
            }
            else
            {
                if (_db.State == ConnectionState.Open) return true;
            }
            try
            {
                Logger.Debug("Open: " + ConnectionString);
                _db.Open();
                switch (_db.State)
                {
                    case ConnectionState.Open: return true;
                    default: return false;
                }
            }
            catch (Exception ex)
            {
                Logger.Exception(ex);
                Close();
                return false;
            }
        }

        /// <summary>关闭连接,并释放对象所占用的系统资源。</summary>
        public void Close()
        {
            if (_db != null)
            {
                Logger.Debug("Close: " + ConnectionString);
                _db.Close();
                _db.Dispose();
                _db = null;
            }
        }

        /// <summary>关闭连接,释放对象所占用的系统资源,并清除连接信息。</summary>
        public void Dispose()
        {
            Close();
            _connectionstring = "";
            _address = "";
            _store = "";
            _user = "";
            _pass = "";
        }

        private IQuery PrivateQuery(string statement, IEnumerable<IDataParameter> parameters)
        {
            if (string.IsNullOrWhiteSpace(statement)) return Example.InvalidQueryStatement;

            const string tablename = "queryresult";

            var connected = Connect();
            if (!connected) return Example.InvalidQueryConnection;

            var query = new Query();
            try
            {
                var command = new SqlCommand();
                command.Connection = _db;
                command.CommandTimeout = Timeout.Query;
                command.CommandText = statement;
                if (parameters != null)
                {
                    foreach (var parameter in parameters)
                    {
                        if (parameter != null) command.Parameters.Add(parameter);
                    }
                }
                using (var dataset = new DataSet())
                {
                    using (var dataadapter = new SqlDataAdapter(statement, _db))
                    {
                        dataadapter.Fill(dataset, tablename);
                        query.Table = dataset.Tables[tablename];
                    }
                }
                command.Dispose();
                query.Success = true;
            }
            catch (Exception exception)
            {
                Logger.Exception(exception);
                query.Success = false;
                query.Exception = exception;
            }
            return query;
        }

        /// <summary>执行单条 Transact-SQL 语句,并加入参数。</summary>
        public IExecute PrivateExecute(string statement, IEnumerable<IDataParameter> parameters)
        {
            if (string.IsNullOrWhiteSpace(statement)) return Example.InvalidExecuteStatement;

            var connected = Connect();
            if (!connected) return Example.InvalidExecuteConnection;

            var transaction = _db.BeginTransaction();
            var execute = new Execute();
            try
            {
                var command = new SqlCommand();
                command.Connection = _db;
                command.Transaction = transaction;
                command.CommandTimeout = Timeout.Execute;
                command.CommandText = statement;
                if (parameters != null)
                {
                    foreach (var parameter in parameters)
                    {
                        if (parameter != null) command.Parameters.Add(parameter);
                    }
                }
                execute.Rows += command.ExecuteNonQuery();
                transaction.Commit();
                command.Dispose();
                execute.Success = true;
            }
            catch (Exception exception)
            {
                try { transaction.Rollback(); } catch { }
                Logger.Exception(exception);
                execute.Success = false;
                execute.Exception = exception;
            }
            try { transaction.Dispose(); } catch { }
            return execute;
        }

        /// <summary>查询。</summary>
        public IQuery Query(string statement)
        {
            return PrivateQuery(statement, null);
        }

        /// <summary>查询。</summary>
        public IQuery Query(string statement, IEnumerable<IDataParameter> parameters)
        {
            if (parameters == null) return Example.InvalidQueryParameters;
            return PrivateQuery(statement, parameters);
        }

        /// <summary>执行。</summary>
        public IExecute Execute(string statement)
        {
            return PrivateExecute(statement, null);
        }

        /// <summary>执行。</summary>
        public IExecute Execute(string statement, IEnumerable<IDataParameter> parameters)
        {
            if (parameters == null) return Example.InvalidExecuteParameters;
            return PrivateExecute(statement, parameters);
        }

        #endregion

        #region 属性。

        /// <summary>获取当前的 SqlConnection 对象。</summary>
        public SqlConnection Connection
        {
            get { return _db; }
        }

        /// <summary>获取或设置连接字符串。</summary>
        public string ConnectionString
        {
            get { return _connectionstring; }
            set { _connectionstring = value ?? ""; _address = ""; _store = ""; _user = ""; _pass = ""; }
        }

        /// <summary>获取或设置数据库服务器的地址。</summary>
        public string Address
        {
            get { return _address; }
            set { _address = value ?? ""; UpdateConnectString(); }
        }

        /// <summary>获取或设置数据库名称。</summary>
        public string Store
        {
            get { return _store; }
            set { _store = value ?? ""; UpdateConnectString(); }
        }

        /// <summary>获取或设置用于连接数据库服务器的用户名,为空则使用 Windows 用户登录。</summary>
        public string User
        {
            get { return _user; }
            set { _user = value ?? ""; UpdateConnectString(); }
        }

        /// <summary>获取或设置用于连接数据库服务器的密码。</summary>
        public string Pass
        {
            get { return _pass; }
            set { _pass = value ?? ""; UpdateConnectString(); }
        }

        /// <summary>获取或设置超时。</summary>
        public Timeout Timeout
        {
            get { return _timeout; }
            set { _timeout = value; }
        }

        #endregion

        #region 方法。

        /// <summary>指定连接凭据后,是否符合连接要求。</summary>
        public bool Proven()
        {
            return Proven(_address, _store, _user, _pass);
        }

        private void UpdateConnectString()
        {
            _connectionstring = "";
            _connectionstring += "data source = " + _address + "; ";
            _connectionstring += "initial catalog = " + _store + "; ";
            if (string.IsNullOrEmpty(User))
            {
                _connectionstring += "integrated security = sspi; ";
            }
            else
            {
                _connectionstring += "user id = " + _user + "; ";
                if (!string.IsNullOrEmpty(_pass)) _connectionstring += "password = " + _pass + "; ";
            }
            _connectionstring += "connection timeout = " + Timeout.Connect.ToString() + ";";
        }

        /// <summary>查询数据库中的所有表名。</summary>
        public List<string> QueryAllTableNames()
        {
            var list = new List<string>();
            if (Connect())
            {
                var sql = "select [name] from [sysobjects] where [type] = 'u' order by [name]; ";
                var query = (Query)Query(sql);
                for (int r = 0; r < query.Rows; r++)
                {
                    var cell = query.Text(r, 0);
                    if (TextUtility.IsBlank(cell)) continue;
                    list.Add(cell);
                }
                query.Dispose();
            }
            return list;
        }

        /// <summary>查询数据库实例中的所有数据库名。</summary>
        public List<string> QueryAllStoreNames()
        {
            var list = new List<string>();
            if (Connect())
            {
                var sql = "select [name] from [master]..[sysdatabases] order by [name]; ";
                var query = (Query)Query(sql);
                for (int r = 0; r < query.Rows; r++)
                {
                    var cell = query.Text(r, 0);
                    if (TextUtility.IsBlank(cell)) continue;
                    if (cell == "master") continue;
                    if (cell == "model") continue;
                    if (cell == "msdb") continue;
                    if (cell == "tempdb") continue;
                    list.Add(cell);
                }
                query.Dispose();
            }
            return list;
        }

        /// <summary>查询表中的所有列名。</summary>
        public List<string> QueryAllColumnNames(string tableName)
        {
            var list = new List<string>();
            if (Connect())
            {
                var table = TextUtility.AntiInject(tableName);
                var sql = TextUtility.Merge("select [name] from [syscolumns] where [id] = object_id('", table, "'); ");
                var query = (Query)Query(sql);
                for (int r = 0; r < query.Rows; r++)
                {
                    var cell = query.Text(r, 0);
                    if (TextUtility.IsBlank(cell)) continue;
                    list.Add(cell);
                }
                query.Dispose();
            }
            return list;
        }

        /// <summary>创建表,当表不存在时创建表,当现存表中缺少模型中属性对应的列时增加列。成功时返回空字符串,发生异常时返回异常信息。</summary>
        public string CreateTable(Record model)
        {
            if (model == null) return "参数无效。";
            var type = model.GetType();
            var error = CreateTable(type);
            return error;
        }

        /// <summary>创建表,当表不存在时创建表,当现存表中缺少模型中属性对应的列时增加列。成功时返回空字符串,发生异常时返回异常信息。</summary>
        public string CreateTable(Type model)
        {
            var structure = null as TableStructure;
            try { structure = TableStructure.ParseModel(model); }
            catch (Exception exception) { return exception.Message; }

            // 连接数据库。
            if (!Connect()) return "连接数据库失败。";

            // 检查现存表。
            var exists = false;
            var tables = QueryAllTableNames();
            if (tables.Count > 0)
            {
                var lower = structure.Table.ToLower();
                foreach (var table in tables)
                {
                    if (TextUtility.IsBlank(table)) continue;
                    if (table.ToLower() == lower)
                    {
                        exists = true;
                        break;
                    }
                }
            }

            if (exists)
            {
                // 获取已存在的列名。
                var columns = QueryAllColumnNames(structure.Table);
                if (columns.Count > 0)
                {
                    var lower = new List<string>();
                    foreach (var column in columns)
                    {
                        if (TextUtility.IsBlank(column)) continue;
                        lower.Add(column.ToLower());
                    }
                    columns = lower;
                }

                // 增加列。
                foreach (var column in structure.Columns.Values)
                {
                    // 检查 Independent 特性。
                    if (structure.Independent && column.Independent) continue;

                    // 去重。
                    var lower = column.Field.ToLower();
                    if (columns.Contains(lower)) continue;

                    var type = GetColumnDeclaration(column);
                    if (type == TextUtility.EmptyString) return TextUtility.Merge("类型 ", column.Type.ToString(), " 不受支持。");

                    var sql = TextUtility.Merge("alter table [", structure.Table, "] add ", type, "; ");
                    var execute = Execute(sql);
                    if (execute.Success == false) return execute.Error;
                }
                return TextUtility.EmptyString;
            }
            else
            {
                var sqlcolumns = new List<string>();
                foreach (var kvp in structure.Columns)
                {
                    var property = kvp.Key;
                    var column = kvp.Value;

                    // 检查 Independent 特性。
                    if (structure.Independent && column.Independent) continue;

                    var type = GetColumnDeclaration(column);
                    if (!column.Independent && property == "Key") type = type + " primary key";

                    if (type == TextUtility.EmptyString) return TextUtility.Merge("类型 ", column.Type.ToString(), " 不受支持。");
                    sqlcolumns.Add(type);
                }
                var sql = TextUtility.Merge("create table [", structure.Table, "](", string.Join(", ", sqlcolumns), "); ");
                var execute = Execute(sql);
                if (execute.Success) return TextUtility.EmptyString;
                return execute.Error;
            }
        }

        /// <summary>插入记录。成功时候返回空字符串,发生异常时返回异常信息。</summary>
        public string Insert(Record entity)
        {
            if (entity == null) return "参数无效。";
            var type = entity.GetType();

            entity.FixProperties();

            var structure = null as TableStructure;
            try { structure = TableStructure.ParseModel(entity); }
            catch (Exception exception) { return exception.Message; }

            var parameters = structure.CreateDataParameters(entity, CreateDataParameter);

            var sql = GenerateInsertStatement(structure.Table, parameters);

            var execute = Execute(sql, parameters);
            if (execute.Success) return TextUtility.EmptyString;
            return execute.Error;
        }

        /// <summary>
        /// <para>更新记录,实体中的 Created 和 Key 属性不被更新。成功时返回空字符串,发生异常时返回异常信息。</para>
        /// <para>无法更新拥有 Independent 特性的模型。</para>
        /// </summary>
        public string Update(Record entity)
        {
            if (entity == null) return "参数无效。";
            var type = entity.GetType();

            entity.FixProperties();
            entity.Updated = ClockUtility.Lucid;

            var structure = null as TableStructure;
            try { structure = TableStructure.ParseModel(entity); }
            catch (Exception exception) { return exception.Message; }

            // 检查 Independent 特性。
            if (structure.Independent) return "无法更新拥有 Independent 特性的模型。";

            var parameters = structure.CreateDataParameters(entity, CreateDataParameter, "_created", "_key");

            var sql = GenerateUpdateStatement(structure.Table, entity.Key, parameters);

            var execute = Execute(sql, parameters);
            if (execute.Success) return TextUtility.EmptyString;
            return execute.Error;
        }

        /// <summary>获取具有指定 Key 的记录。</summary>
        public Result<T> QueryRecord<T>(string key, long flag = 0) where T : Record
        {
            var k = TextUtility.RestrictGuid(key);
            if (TextUtility.IsBlank(k) == false)
            {
                try
                {
                    var type = typeof(T);
                    var ts = TableStructure.ParseModel(type);
                    var f = (flag == 0) ? TextUtility.EmptyString : TextUtility.Merge(" _flag=", flag.ToString(), " and");
                    var query = (Query)Query(TextUtility.Merge("select top 1 * from [", ts.Table, "] where", f, " _key='", k, "'; "));
                    var list = query.Fill<T>();
                    query.Dispose();
                    if (list.Count > 0) return new Result<T>(list[0]);
                }
                catch (Exception argException)
                {
                    return new Result<T>(argException);
                }
            }
            return new Result<T>(new Exception("参数无效。"));
        }

        /// <summary>获取记录。</summary>
        public Result<List<T>> QueryRecords<T>(long flag = 0) where T : Record
        {
            try
            {
                var type = typeof(T);
                var ts = TableStructure.ParseModel(type);
                var f = (flag == 0) ? TextUtility.EmptyString : TextUtility.Merge(" where _flag=", flag.ToString());
                var query = (Query)Query(TextUtility.Merge("select * from [", ts.Table, "]", f, "; "));
                var list = query.Fill<T>();
                query.Dispose();
                return new Result<List<T>>(list);
            }
            catch (Exception argException)
            {
                return new Result<List<T>>(argException);
            }
        }

        /// <summary>获取按指定语句查询到的所有记录。</summary>
        public Result<List<T>> Query<T>(string statement) where T : Record
        {
            var query = (Query)Query(statement);
            if (query.Exception == null)
            {
                var list = query.Fill<T>();
                query.Dispose();
                return new Result<List<T>>(list);
            }
            else
            {
                var result = new Result<List<T>>(query.Exception);
                query.Dispose();
                return result;
            }
        }

        /// <summary>查询有效的 Key 值。</summary>
        public Result<List<string>> QueryKeys(Type model, long flag = 0)
        {
            if (model != null)
            {
                try
                {
                    var type = model;
                    var list = new List<string>();
                    var ts = TableStructure.ParseModel(type);
                    var f = (flag == 0) ? TextUtility.EmptyString : TextUtility.Merge(" where _flag=", flag.ToString());
                    var query = (Query)Query(TextUtility.Merge("select _key from [", ts.Table, "]", f, "; "));
                    for (var r = 0; r < query.Rows; r++)
                    {
                        var cell = TextUtility.Trim(query.Text(r));
                        if (cell.Length > 0) list.Add(cell);
                    }
                    query.Dispose();
                    return new Result<List<string>>(list);
                }
                catch (Exception argException)
                {
                    return new Result<List<string>>(argException);
                }
            }
            return new Result<List<string>>(new Exception("参数无效。"));
        }

        /// <summary>查询有效的 Key 值。</summary>
        public Result<List<string>> QueryKeys<T>(long flag = 0) where T : Record
        {
            try
            {
                var type = typeof(T);

                var ts = TableStructure.ParseModel(type);
                var f = (flag == 0) ? TextUtility.EmptyString : TextUtility.Merge(" where _flag=", flag.ToString());
                var query = (Query)Query(TextUtility.Merge("select _key from [", ts.Table, "]", f, "; "));
                var list = new List<string>();
                for (var r = 0; r < query.Rows; r++)
                {
                    var cell = TextUtility.Trim(query.Text(r));
                    if (cell.Length > 0) list.Add(cell);
                }
                query.Dispose();
                return new Result<List<string>>(list);
            }
            catch (Exception argException)
            {
                return new Result<List<string>>(argException);
            }
        }

        #endregion

        #region 静态方法。

        private static string GetColumnDeclaration(ColumnAttribute column)
        {
            var type = TextUtility.EmptyString;
            var vcolumn = column;
            var length = Math.Max(0, vcolumn.Length);
            switch (vcolumn.Type)
            {
                case ColumnType.Integer:
                    type = "bigint";
                    break;
                case ColumnType.Float:
                    type = "float";
                    break;
                case ColumnType.Binary:
                    type = "image";
                    break;
                case ColumnType.DateTime:
                    type = "datetime";
                    break;
                case ColumnType.VarChar:
                    type = TextUtility.Merge("varchar(", Math.Min(8000, length).ToString(), ")");
                    break;
                case ColumnType.VarChar255:
                    type = TextUtility.Merge("varchar(255)");
                    break;
                case ColumnType.VarCharMax:
                    type = TextUtility.Merge("varchar(max)");
                    break;
                case ColumnType.Text:
                    type = TextUtility.Merge("text");
                    break;
                case ColumnType.NVarChar:
                    type = TextUtility.Merge("nvarchar(", Math.Min(4000, length).ToString(), ")");
                    break;
                case ColumnType.NVarChar255:
                    type = TextUtility.Merge("nvarchar(255)");
                    break;
                case ColumnType.NVarCharMax:
                    type = TextUtility.Merge("nvarchar(max)");
                    break;
                case ColumnType.NText:
                    type = TextUtility.Merge("ntext");
                    break;
                default:
                    return TextUtility.EmptyString;
            }
            return TextUtility.Merge("[", vcolumn.Field, "] ", type);
        }

        /// <summary>创建参数。</summary>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        internal static SqlParameter CreateDataParameter(Parameter parameter)
        {
            if (parameter == null) throw new InvalidOperationException("参数无效。");
            return CreateDataParameter(parameter.Name, parameter.Type, parameter.Size, parameter.Value);
        }

        /// <summary>创建参数。</summary>
        public static SqlParameter CreateDataParameter(string name, ColumnType type, Int32 size, object value)
        {
            var vname = TextUtility.Trim(name);
            if (TextUtility.IsBlank(vname)) return null;

            var vtype = SqlDbType.BigInt;
            switch (type)
            {
                case ColumnType.Binary:
                    vtype = SqlDbType.Image;
                    break;
                case ColumnType.Integer:
                    vtype = SqlDbType.BigInt;
                    break;
                case ColumnType.Float:
                    vtype = SqlDbType.Float;
                    break;
                case ColumnType.DateTime:
                    vtype = SqlDbType.DateTime;
                    break;
                case ColumnType.VarChar:
                case ColumnType.VarChar255:
                case ColumnType.VarCharMax:
                    vtype = SqlDbType.VarChar;
                    break;
                case ColumnType.NVarChar:
                case ColumnType.NVarChar255:
                case ColumnType.NVarCharMax:
                    vtype = SqlDbType.VarChar;
                    break;
                case ColumnType.Text:
                    vtype = SqlDbType.Text;
                    break;
                case ColumnType.NText:
                    vtype = SqlDbType.NText;
                    break;
                default:
                    throw new InvalidOperationException(TextUtility.Merge("类型 ", type.ToString(), " 不受支持。"));
            }

            var vsize = size;
            switch (type)
            {
                case ColumnType.VarChar:
                    vsize = NumberUtility.RestrictValue(vsize, 0, 8000);
                    break;
                case ColumnType.NVarChar:
                    vsize = NumberUtility.RestrictValue(vsize, 0, 4000);
                    break;
                case ColumnType.VarChar255:
                case ColumnType.NVarChar255:
                    vsize = NumberUtility.RestrictValue(vsize, 0, 255);
                    break;
                default:
                    vsize = 0;
                    break;
            }

            var vvalue = value;
            if (vvalue is string && vvalue != null && vsize > 0)
            {
                vvalue = TextUtility.RestrictLength((string)vvalue, vsize);
            }

            var parameter = new SqlParameter();
            parameter.ParameterName = vname;
            parameter.SqlDbType = vtype;
            parameter.Value = vvalue;
            if (vsize > 0) parameter.Size = vsize;
            return parameter;
        }

        /// <summary>创建参数。</summary>
        public static SqlParameter CreateDataParameter(String name, SqlDbType type, Int32 size, Object value)
        {
            if (value is string && value != null && size > 0)
            {
                value = TextUtility.RestrictLength((string)value, (int)size);
            }

            var p = new SqlParameter();
            p.ParameterName = name ?? "";
            p.SqlDbType = type;
            p.Size = size;
            p.Value = value;
            return p;
        }

        /// <summary>创建参数。</summary>
        public static SqlParameter CreateDataParameter(String name, SqlDbType type, Object value)
        {
            var p = new SqlParameter();
            p.ParameterName = name ?? "";
            p.SqlDbType = type;
            p.Value = value;
            return p;
        }

        ///// <summary>枚举本地网络中服务器的名称。</summary>
        //public static List<string> EnumerateServer()
        //{
        //    // 表中列名:ServerName、InstanceName、IsClustered、Version。
        //    var table = SqlDataSourceEnumerator.Instance.GetDataSources();
        //    var query = new Query();
        //    query.Success = table != null;
        //    query.Table = table;
        //    var list = new List<string>();
        //    for (int i = 0; i < query.Rows; i++)
        //    {
        //        var sn = query.Text(i, "ServerName");
        //        if (!string.IsNullOrEmpty(sn)) list.Add(sn);
        //    }
        //    query.Dispose();
        //    return list;
        //}

        /// <summary>指定的连接凭据是否符合连接要求。</summary>
        public static bool Proven(SqlServer sqlserver)
        {
            return Proven(sqlserver._address, sqlserver._store, sqlserver._user, sqlserver._pass);
        }

        /// <summary>指定的连接凭据是否符合连接要求,默认指定 master 数据库。</summary>
        public static bool Proven(string address, string user, string pass)
        {
            return Proven(address, "master", user, pass);
        }

        /// <summary>指定的连接凭据是否符合连接要求。</summary>
        public static bool Proven(string address, string store, string user, string pass)
        {
            var a = string.IsNullOrEmpty(address);
            var s = string.IsNullOrEmpty(store);
            var u = string.IsNullOrEmpty(user);
            var p = string.IsNullOrEmpty(pass);
            if (a) return false;
            if (s) return false;
            if (u && !p) return false;
            return true;
        }

        #endregion

        #region Linq Utility

        private static string GetParameterName(string parameter)
        {
            var name = TextUtility.AntiInject(parameter, 255);
            if (name.StartsWith("@") && name.Length > 1)
            {
                name = name.Substring(1, name.Length - 1);
            }
            return name;
        }

        private static string GetParameterName(IDataParameter parameter)
        {
            var name = TextUtility.EmptyString;
            if (parameter != null)
            {
                name = GetParameterName(parameter.ParameterName);
            }
            return name;
        }

        private static List<string> GetParametersNames(IEnumerable<IDataParameter> parameters)
        {
            var columns = new List<string>();
            if (parameters != null)
            {
                foreach (var parameter in parameters)
                {
                    var name = GetParameterName(parameter);
                    var isblank = TextUtility.IsBlank(name);
                    if (isblank) continue;
                    columns.Add(name);
                }
            }
            return columns;
        }

        private static string GenerateInsertStatement(string table, List<string> columns)
        {
            var result = TextUtility.EmptyString;
            var vtable = TextUtility.AntiInject(table, 255);
            if (columns != null && !TextUtility.IsBlank(vtable))
            {
                var count = 0;
                var names = new List<string>();
                var values = new List<string>();
                foreach (var column in columns)
                {
                    //names.Add(TextGenerator.Merge("[", column, "]"));
                    names.Add(TextUtility.Merge(column));
                    values.Add("@" + column);
                    count += 1;
                }
                var text = new StringBuilder();
                if (count > 0)
                {
                    text.Append("insert into [", vtable, "](", string.Join(", ", names), ") ");
                    text.Append("values(", string.Join(", ", values), "); ");
                }
                result = text.ToString();
            }
            return result;
        }

        private static string GenerateUpdateStatement(string table, string key, List<string> columns)
        {
            var result = TextUtility.EmptyString;
            var vtable = TextUtility.AntiInject(table, 255);
            var vkey = TextUtility.AntiInject(key, 255);
            if (columns != null && !TextUtility.IsBlank(vtable) && !TextUtility.IsBlank(vkey))
            {
                var items = new List<string>();
                foreach (var column in columns)
                {
                    items.Add(TextUtility.Merge("[", column, "]=@", column));
                }
                if (items.Count > 0)
                {
                    result = TextUtility.Merge("update [", vtable, "] set ", string.Join(", ", items), " where [_key]='", vkey, "'; ");
                }
            }
            return result;
        }

        /// <summary>生成 INSERT INTO 语句。表名必须有效,无有效参数时将获取空结果。</summary>
        /// <exception cref="System.ArgumentException"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static string GenerateInsertStatement(string table, IEnumerable<IDataParameter> parameters)
        {
            if (table == null) throw new ArgumentNullException("argTable");
            var vtable = TextUtility.AntiInject(table, 255);
            if (TextUtility.IsBlank(vtable)) throw new ArgumentException("表名无效。", "argTable");

            var vcolumns = GetParametersNames(parameters);
            if (vcolumns.Count < 1) return TextUtility.EmptyString;

            return GenerateInsertStatement(vtable, vcolumns);
        }

        /// <summary>生成 UPDATE 语句,键字段名为“_key”。表名必须有效,键值必须有效,无有效参数时将获取空结果。</summary>
        /// <exception cref="System.ArgumentException"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static string GenerateUpdateStatement(string table, string key, IEnumerable<IDataParameter> parameters)
        {
            if (table == null) throw new ArgumentNullException("argTable");
            var vtable = TextUtility.AntiInject(table, 255);
            if (TextUtility.IsBlank(vtable)) throw new ArgumentException("表名无效。", "argTable");

            if (key == null) throw new ArgumentNullException("argKey");
            var vkey = TextUtility.AntiInject(key, 255);
            if (TextUtility.IsBlank(vkey)) throw new ArgumentException("键值无效。", "argKey");

            var vcolumns = GetParametersNames(parameters);
            if (vcolumns.Count < 1) return TextUtility.EmptyString;

            return GenerateUpdateStatement(vtable, vkey, vcolumns);
        }

        #endregion

    }

}

#endif