using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using Neo.Afx.ComponentModel;
using Neo.Afx.Services.Integration;

namespace Neo.Afx.Integration
{
    /// <summary>
    /// The integration data source.
    /// </summary>
    public partial class DataSource
    {
        /// <summary>
        /// Gets the data from the named data source.
        /// </summary>
        /// <param name="name">The name of the data source to be used.</param>
        /// <param name="queryString">The query string to be used.</param>
        /// <returns>The data from the named data source</returns>
        [SqlFunction(
            IsDeterministic = true,
            IsPrecise = true,
            DataAccess = DataAccessKind.Read,
            SystemDataAccess = SystemDataAccessKind.None
            )]
        public static SqlXml GetData(SqlString name, SqlString queryString)
        {
            SqlIntegrationStore dataStore = null;
            try
            {
                dataStore = new SqlIntegrationStore(SqlUtilities.ClrConnectionString);
                dataStore.Open();
                var data = dataStore.GetData(name.Value, queryString.Value);
                return new SqlXml(data.CreateReader());
            }
            finally
            {
                if(dataStore != null)
                {
                    dataStore.Close();
                }
            }
        }

        /// <summary>
        /// Invokes the named data source.
        /// </summary>
        /// <param name="name">The name of the data source to be invoked.</param>
        /// <param name="queryString">The query string to be invoked.</param>
        /// <returns>The result of invoking the named data source</returns>
        [SqlFunction(
            IsDeterministic = true,
            IsPrecise = true,
            DataAccess = DataAccessKind.Read,
            SystemDataAccess = SystemDataAccessKind.None
            )]
        public static SqlXml Invoke(SqlString name, SqlString queryString)
        {
            return GetData(name, queryString);
        }

        /// <summary>
        /// Invokes the named data source using the given request query.
        /// </summary>
        /// <param name="name">The name of the data source to be invoked.</param>
        /// <param name="requestQuery">The request query to be used - overrides the database value.</param>
        /// <returns>The result of invoking the named data source</returns>
        [SqlFunction(
            IsDeterministic = true,
            IsPrecise = true,
            DataAccess = DataAccessKind.Read,
            SystemDataAccess = SystemDataAccessKind.None
            )]
        public static SqlXml InvokeQuery(SqlString name, SqlString requestQuery)
        {
            SqlIntegrationStore dataStore = null;
            try
            {
                dataStore = new SqlIntegrationStore(SqlUtilities.ClrConnectionString);
                dataStore.Open();
                var data = dataStore.GetData(name.Value, null, requestQuery.Value);
                return new SqlXml(data.CreateReader());
            }
            finally
            {
                if(dataStore != null)
                {
                    dataStore.Close();
                }
            }

        }
    }
}