mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-20 04:48:53 +00:00
146 lines
No EOL
4.7 KiB
C#
146 lines
No EOL
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace DapperExtensions.Sql
|
|
{
|
|
public class SqlServerDialect : SqlDialectBase
|
|
{
|
|
public override char OpenQuote
|
|
{
|
|
get { return '['; }
|
|
}
|
|
|
|
public override char CloseQuote
|
|
{
|
|
get { return ']'; }
|
|
}
|
|
|
|
public override string GetIdentitySql(string tableName)
|
|
{
|
|
return string.Format("SELECT CAST(SCOPE_IDENTITY() AS BIGINT) AS [Id]");
|
|
}
|
|
|
|
public override string GetPagingSql(string sql, int page, int resultsPerPage, IDictionary<string, object> parameters)
|
|
{
|
|
int startValue = (page * resultsPerPage) + 1;
|
|
return GetSetSql(sql, startValue, resultsPerPage, parameters);
|
|
}
|
|
|
|
public override string GetSetSql(string sql, int firstResult, int maxResults, IDictionary<string, object> parameters)
|
|
{
|
|
if (string.IsNullOrEmpty(sql))
|
|
{
|
|
throw new ArgumentNullException("SQL");
|
|
}
|
|
|
|
if (parameters == null)
|
|
{
|
|
throw new ArgumentNullException("Parameters");
|
|
}
|
|
|
|
int selectIndex = GetSelectEnd(sql) + 1;
|
|
string orderByClause = GetOrderByClause(sql);
|
|
if (orderByClause == null)
|
|
{
|
|
orderByClause = "ORDER BY CURRENT_TIMESTAMP";
|
|
}
|
|
|
|
|
|
string projectedColumns = GetColumnNames(sql).Aggregate(new StringBuilder(), (sb, s) => (sb.Length == 0 ? sb : sb.Append(", ")).Append(GetColumnName("_proj", s, null)), sb => sb.ToString());
|
|
string newSql = sql
|
|
.Replace(" " + orderByClause, string.Empty)
|
|
.Insert(selectIndex, string.Format("ROW_NUMBER() OVER(ORDER BY {0}) AS {1}, ", orderByClause.Substring(9), GetColumnName(null, "_row_number", null)));
|
|
|
|
string result = string.Format("SELECT TOP({0}) {1} FROM ({2}) [_proj] WHERE {3} >= @_pageStartRow ORDER BY {3}",
|
|
maxResults, projectedColumns.Trim(), newSql, GetColumnName("_proj", "_row_number", null));
|
|
|
|
parameters.Add("@_pageStartRow", firstResult);
|
|
return result;
|
|
}
|
|
|
|
protected string GetOrderByClause(string sql)
|
|
{
|
|
int orderByIndex = sql.LastIndexOf(" ORDER BY ", StringComparison.CurrentCultureIgnoreCase);
|
|
if (orderByIndex == -1)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
string result = sql.Substring(orderByIndex).Trim();
|
|
|
|
int whereIndex = result.IndexOf(" WHERE ", StringComparison.CurrentCultureIgnoreCase);
|
|
if (whereIndex == -1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
return result.Substring(0, whereIndex).Trim();
|
|
}
|
|
|
|
protected int GetFromStart(string sql)
|
|
{
|
|
int selectCount = 0;
|
|
string[] words = sql.Split(' ');
|
|
int fromIndex = 0;
|
|
foreach (var word in words)
|
|
{
|
|
if (word.Equals("SELECT", StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
selectCount++;
|
|
}
|
|
|
|
if (word.Equals("FROM", StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
selectCount--;
|
|
if (selectCount == 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
fromIndex += word.Length + 1;
|
|
}
|
|
|
|
return fromIndex;
|
|
}
|
|
|
|
protected virtual int GetSelectEnd(string sql)
|
|
{
|
|
if (sql.StartsWith("SELECT DISTINCT", StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
return 15;
|
|
}
|
|
|
|
if (sql.StartsWith("SELECT", StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
return 6;
|
|
}
|
|
|
|
throw new ArgumentException("SQL must be a SELECT statement.", "sql");
|
|
}
|
|
|
|
protected virtual IList<string> GetColumnNames(string sql)
|
|
{
|
|
int start = GetSelectEnd(sql);
|
|
int stop = GetFromStart(sql);
|
|
string[] columnSql = sql.Substring(start, stop - start).Split(',');
|
|
List<string> result = new List<string>();
|
|
foreach (string c in columnSql)
|
|
{
|
|
int index = c.IndexOf(" AS ", StringComparison.CurrentCultureIgnoreCase);
|
|
if (index > 0)
|
|
{
|
|
result.Add(c.Substring(index + 4).Trim());
|
|
continue;
|
|
}
|
|
|
|
string[] colParts = c.Split('.');
|
|
result.Add(colParts[colParts.Length - 1].Trim());
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
} |