using System;
using System.Data;
using System.Data.SqlClient;

namespace ynhtm.DBUtility
{
    public sealed class SqlDb : DbBase
    {
        SqlConnection connection = null;

        public SqlDb()
            : this(DbBase.CONNECTIONSTRING)
        { }

        public SqlDb(string connectionString)
        {
            this.ConnectionString = connectionString;
        }

        public override IDbConnection Connection
        {
            get
            {
                if (connection == null) this.connection = new SqlConnection(this.ConnectionString);
                return this.connection;
            }
        }

        public override string IDentity
        {
            get { return "SELECT SCOPE_IDENTITY()"; }
        }

        public override string IsNull
        {
            get { return "ISNULL"; }
        }

        public override string Now
        {
            get { return "GETDATE()"; }
        }

        public string ConnectionString { get; private set; }

        public override IDataParameter CreateParameter(string name, object value)
        {
            return new SqlParameter("@" + name, value == null ? DBNull.Value : value);
        }

        protected override DataTable GetPagex(ref int recordCount, string table, string order, int pageSize, int pageIndex, string query, string field)
        {
            var par = new SqlParameter("@RecordCount", recordCount) { Direction = ParameterDirection.InputOutput };
            using (var cmd = base.CreateCommand("ynhtm_GetPage",
                new SqlParameter("@Table", table),
                new SqlParameter("@Order", order),
                new SqlParameter("@PageSize", pageSize),
                new SqlParameter("@PageIndex", pageIndex),
                par,
                new SqlParameter("@Query", query),
                new SqlParameter("@Field", field)))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                base.Open();
                using (var reader = cmd.ExecuteReader())
                {
                    var result = new DataTable();
                    result.Load(reader);
                    recordCount = Convert.ToInt32(par.Value);
                    return result;
                }
            }
        }

        protected override DataTable GetPagex(string table, string order, int pageSize, int pageIndex, string query, string field)
        {
            using (var cmd = base.CreateCommand("ynhtm_GetPage",
                new SqlParameter("@Table", table),
                new SqlParameter("@Order", order),
                new SqlParameter("@PageSize", pageSize),
                new SqlParameter("@PageIndex", pageIndex),
                new SqlParameter("@Query", query),
                new SqlParameter("@Field", field)))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                base.Open();
                using (var reader = cmd.ExecuteReader())
                {
                    var result = new DataTable();
                    result.Load(reader);
                    return result;
                }
            }
        }

        public override void Backup(string path)
        {
            this.ExecuteNonQuery("DECLARE @Name NVARCHAR(128);SELECT @Name = DB_NAME();BACKUP DATABASE @Name TO DISK = {0};", path);
        }

        public override string Name
        {
            get { return this.Connection.Database; }
        }

        public override string Size
        {
            get
            {
                using (var cmd = this.CreateCommand("SP_SPACEUSED"))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    base.Open();
                    using (var reader = cmd.ExecuteReader())
                    {
                        if (!reader.Read()) return null;
                        return reader.GetString("database_size");
                    }
                }
            }
        }

        public override string Version
        {
            get
            {
                base.Open();
                return ((SqlConnection)this.Connection).ServerVersion;
            }
        }
    }
}