﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sage.SalesLogix.NHibernate;
using NHibernate.SqlCommand;

/*
   OpenSlx - Open Source SalesLogix Library and Tools
   Copyright 2010 nicocrm (http://github.com/ngaller/OpenSlx)

   Licensed 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.
*/

namespace OpenSlx.Lib.Db
{
    /// <summary>
    /// A custom SalesLogix SQL dialect for NHibernate.  This can be used to introduce custom constructs in the
    /// SQL generated by NHibernate.
    /// 
    /// To use this dialect, either edit the hibernate.xml file under the deployed web site, and add it to the 
    /// supportfiles, or edit the code template for the hibernate.xml file, under 
    /// Model\Entity Model\CodeTemplates\Entity.
    /// </summary>
    public class SlxCustomDialect : SLXDialect
    {
        /// <summary>
        /// Return customized limit string (for paging queries)
        /// For performance reason the limit string is ommitted when querying the first page.
        /// </summary>
        /// <param name="querySqlString"></param>
        /// <param name="offset"></param>
        /// <param name="last"></param>
        /// <returns></returns>
        public override NHibernate.SqlCommand.SqlString GetLimitString(NHibernate.SqlCommand.SqlString querySqlString, SqlString offsetString, SqlString lastString)
        {
            if (!querySqlString.StartsWithCaseInsensitive("select "))
            {
                throw new ArgumentException("querySqlString should start with select", "querySqlString");
            }
            SqlString sqlString = querySqlString.Substring(6);
            string orderSql = querySqlString.SubstringStartingWithLast("order by").ToString();
            if (orderSql.Length != 0)
            {
                sqlString = sqlString.Substring(0, (sqlString.Length - orderSql.Length) - 1);
            }
            SqlStringBuilder builder = new SqlStringBuilder();
            int offset;
            if (!int.TryParse(offsetString.ToString(), out offset))
                offset = 0;
            int last;
            if (!int.TryParse(lastString.ToString(), out last))
                last = -1;
            int num = offset + 1;
            builder.Add("SELECT TOP ").Add(last.ToString()).Add(" ").Add(sqlString);
            if(offset > 0)
                builder.Add(" WITH FIRSTROW ").Add(num.ToString());
            if (orderSql.Length > 0)
            {
                builder.Add(" ").Add(orderSql);
            }
            return builder.ToSqlString();
        }
    }
}
