虚谷数据库

This commit is contained in:
sunkaixuan
2024-06-27 11:20:20 +08:00
parent 706e63a75a
commit 3518862257
28 changed files with 3144 additions and 1 deletions

View File

@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar.Xugu
{
public class XuguBlukCopy
{
internal List<IGrouping<int, DbColumnInfo>> DbColumnInfoList { get; set; }
internal SqlSugarProvider Context { get; set; }
internal ISqlBuilder Builder { get; set; }
internal InsertBuilder InsertBuilder { get; set; }
internal object[] Inserts { get; set; }
public int ExecuteBulkCopy()
{
if (DbColumnInfoList == null || DbColumnInfoList.Count == 0) return 0;
if (Inserts.First().GetType() == typeof(DataTable)) return WriteToServer();
DataTable dt = GetCopyData();
SqlBulkCopy bulkCopy = GetBulkCopyInstance();
bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString;
try
{
bulkCopy.WriteToServer(dt);
}
catch (Exception ex)
{
CloseDb();
throw ex;
}
CloseDb();
return DbColumnInfoList.Count;
}
public async Task<int> ExecuteBulkCopyAsync()
{
if (DbColumnInfoList == null || DbColumnInfoList.Count == 0) return 0;
if (Inserts.First().GetType() == typeof(DataTable)) return WriteToServer();
DataTable dt=GetCopyData();
SqlBulkCopy bulkCopy = GetBulkCopyInstance();
bulkCopy.DestinationTableName = InsertBuilder.GetTableNameString;
try
{
await bulkCopy.WriteToServerAsync(dt);
}
catch (Exception ex)
{
CloseDb();
throw ex;
}
CloseDb();
return DbColumnInfoList.Count;
}
private int WriteToServer()
{
var dt = this.Inserts.First() as DataTable;
if (dt == null) return 0;
Check.Exception(dt.TableName == "Table", "dt.TableName can't be null ");
dt = GetCopyWriteDataTable(dt);
SqlBulkCopy copy = GetBulkCopyInstance();
copy.DestinationTableName = this.Builder.GetTranslationColumnName(dt.TableName);
copy.WriteToServer(dt);
CloseDb();
return dt.Rows.Count;
}
private DataTable GetCopyWriteDataTable(DataTable dt)
{
var result = this.Context.Ado.GetDataTable("select top 0 * from " + this.Builder.GetTranslationColumnName(dt.TableName));
foreach (DataRow item in dt.Rows)
{
DataRow dr= result.NewRow();
foreach (DataColumn column in result.Columns)
{
if (dt.Columns.Cast<DataColumn>().Select(it => it.ColumnName.ToLower()).Contains(column.ColumnName.ToLower()))
{
dr[column.ColumnName] = item[column.ColumnName];
if (dr[column.ColumnName] == null) dr[column.ColumnName] = DBNull.Value;
}
}
result.Rows.Add(dr);
}
result.TableName = dt.TableName;
return result;
}
private SqlBulkCopy GetBulkCopyInstance()
{
SqlBulkCopy copy;
if (this.Context.Ado.Transaction == null)
copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection);
else
copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.CheckConstraints, (SqlTransaction)this.Context.Ado.Transaction);
if (this.Context.Ado.Connection.State == ConnectionState.Closed) this.Context.Ado.Connection.Open();
copy.BulkCopyTimeout = this.Context.Ado.CommandTimeOut;
return copy;
}
private DataTable GetCopyData()
{
var dt = this.Context.Ado.GetDataTable("select top 0 * from " + InsertBuilder.GetTableNameString);
foreach (var rowInfos in DbColumnInfoList)
{
var dr = dt.NewRow();
foreach (var value in rowInfos)
{
if (value.Value != null && UtilMethods.GetUnderType(value.Value.GetType()) == UtilConstants.DateType)
{
if (value.Value != null && value.Value.ToString() == DateTime.MinValue.ToString())
value.Value = Convert.ToDateTime("1753/01/01");
}
if (value.Value == null) value.Value = DBNull.Value;
dr[value.DbColumnName] = value.Value;
}
dt.Rows.Add(dr);
}
return dt;
}
private void CloseDb()
{
if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Context.Ado.Transaction == null) this.Context.Ado.Connection.Close();
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Linq;
namespace SqlSugar.Xugu
{
public class XuguBuilder : SqlBuilderProvider
{
public override string SqlParameterKeyWord => ":";
public override string SqlTranslationLeft { get; } =string.Empty;
public override string SqlTranslationRight { get; } = string.Empty;
public override string GetNoTranslationColumnName(string name) => name;
public override string SqlDateNow { get; } = "SYSDATE";
public override string FullSqlDateNow { get; } = "SELECT SYSDATE FROM DUAL";
public override string GetTranslationTableName(string name)
{
Check.ArgumentNullException(name, string.Format(ErrorMessage.ObjNotExist, "Table Name"));
if (!name.Contains("<>f__AnonymousType") && name.IsContainsIn("(", ")") && name != "Dictionary`2") return name;
if (Context.MappingTables == null) return name;
var context = this.Context;
var mappingInfo = context
.MappingTables
.FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase));
name = (mappingInfo == null ? name : mappingInfo.DbTableName);
if (name.IsContainsIn("(", ")", SqlTranslationLeft)) return name;
if (name.Contains(".")) return string.Join(".", name.Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight));
else return SqlTranslationLeft + name + SqlTranslationRight;
}
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar.Xugu
{
public class XuguDeleteBuilder : DeleteBuilder { }
}

View File

@@ -0,0 +1,97 @@
using System;
namespace SqlSugar.Xugu
{
public partial class XuguExpressionContext : ExpressionContext, ILambdaExpressions
{
public override string SqlParameterKeyWord => ":";
public SqlSugarProvider Context { get; set; }
public XuguExpressionContext() => base.DbMehtods = new XuguMethod();
public override string SqlTranslationLeft { get; } = string.Empty;
public override string SqlTranslationRight { get; } = string.Empty;
public override bool IsTranslationText(string name)=> name.IsContainsIn(UtilConstants.Space, "(", ")");
public override string GetLimit() => "";
}
public partial class XuguMethod : DefaultDbMethod, IDbMethods
{
public override string ParameterKeyWord { get; set; } = ":";
public override string Length(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" LENGTH({0}) ", parameter.MemberName);
}
public override string IsNull(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter1 = model.Args[1];
return string.Format("NVL({0},{1})", parameter.MemberName, parameter1.MemberName);
}
public override string MergeString(params string[] strings)=> string.Join("||", strings);
public override string GetRandom()=> " SYS_GUID() ";
public override string GetForXmlPath() => null;// " FOR XML PATH('')),1,len(N','),'') ";
public override string GetStringJoinSelector(string result, string separator)=> $"REPLACE(WM_CONCAT({result}),',','{separator}')";
public override string DateValue(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var type = (DateType)Enum.Parse(typeof(DateType), parameter2.MemberValue.ObjToString(), false);
switch (type)
{
case DateType.Year: return $"GETYEAR({parameter.MemberName})";
case DateType.Month: return $"GETMONTH({parameter.MemberName})";
case DateType.Day: return $"GETDAY({parameter.MemberName})";
case DateType.Hour: return $"GETHOUR({parameter.MemberName})";
case DateType.Minute: return $"GETMINUTE({parameter.MemberName})";
case DateType.Second: return $"GETSECOND({parameter.MemberName})";
case DateType.Weekday: return $"DAYOFWEEK({parameter.MemberName})";
case DateType.Quarter: return $"CEIL(GETMONTH({parameter.MemberName})/3)";
case DateType.Millisecond:
default: return $"DAYOFYEAR({parameter.MemberName})";
}
}
public override string GetDate() => " SYSDATE ";
public override string HasValue(MethodCallExpressionModel model)
{
if (model.Args[0].Type == UtilConstants.GuidType)
{
var parameter = model.Args[0];
return string.Format("( {0} IS NOT NULL )", parameter.MemberName);
}
else
{
var parameter = model.Args[0];
return string.Format("( {0}<>'' AND {0} IS NOT NULL )", parameter.MemberName);
}
}
public override string CharIndex(MethodCallExpressionModel model)
{
return string.Format("INSTR ({0},{1},1,1) ", model.Args[0].MemberName, model.Args[1].MemberName);
}
public override string Contains(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ({0} like '%'||{1}||'%') ", parameter.MemberName, parameter2.MemberName);
}
public override string StartsWith(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ({0} like {1}||'%') ", parameter.MemberName, parameter2.MemberName);
}
public override string EndsWith(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ({0} like '%'||{1}) ", parameter.MemberName, parameter2.MemberName);
}
public override string ToString(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS NVARCHAR)", parameter.MemberName);
}
}
}

View File

@@ -0,0 +1,44 @@
using Microsoft.Data.SqlClient;
using System;
using System.Data;
using System.Threading.Tasks;
namespace SqlSugar.Xugu
{
public class XuguFastBuilder:FastBuilder,IFastBuilder
{
public override bool IsActionUpdateColumns { get; set; } = true;
public override DbFastestProperties DbFastestProperties { get; set; } = new DbFastestProperties() {
HasOffsetTime=true
};
public async Task<int> ExecuteBulkCopyAsync(DataTable dt)
{
SqlBulkCopy bulkCopy = GetBulkCopyInstance();
bulkCopy.DestinationTableName = dt.TableName;
try
{
await bulkCopy.WriteToServerAsync(dt);
}
catch (Exception ex)
{
CloseDb();
throw ex;
}
CloseDb();
return dt.Rows.Count;
}
public SqlBulkCopy GetBulkCopyInstance()
{
SqlBulkCopy copy;
if (this.Context.Ado.Transaction == null)
copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection);
else
copy = new SqlBulkCopy((SqlConnection)this.Context.Ado.Connection, SqlBulkCopyOptions.CheckConstraints, (SqlTransaction)this.Context.Ado.Transaction);
if (this.Context.Ado.Connection.State == ConnectionState.Closed) this.Context.Ado.Connection.Open();
copy.BulkCopyTimeout = this.Context.Ado.CommandTimeOut;
return copy;
}
}
}

View File

@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar.Xugu
{
public class XuguInsertBuilder : InsertBuilder
{
public override string SqlTemplateBatch { get; } = "INSERT into {0} ({1})";
public override string SqlTemplate
{
get
{
if (IsReturnIdentity)
{
return @"INSERT INTO {0}
({1})
VALUES
({2}) RETURNING $PrimaryKey未实现返回主键 " + UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", "");
}
else
{
return @"INSERT INTO {0}
({1})
VALUES
({2}) " + UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", "");
}
}
}
public override string GetTableNameString
{
get
{
var result = Builder.GetTranslationTableName(EntityInfo.EntityName);
result += UtilConstants.Space;
if (this.TableWithString.HasValue()) result += TableWithString + UtilConstants.Space;
return result;
}
}
public override string ToSqlString()
{
if (IsNoInsertNull) DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList();
var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList();
var isSingle = groupList.Count() == 1;
string columnsString = string.Join(",", groupList.First().Select(it => Builder.GetTranslationColumnName(it.DbColumnName)));
if (isSingle)
{
string columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it => base.GetDbColumn(it, Builder.SqlParameterKeyWord + it.DbColumnName)));
return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString);
}
else
{
StringBuilder batchInsetrSql = new StringBuilder();
int pageSize = groupList.Count;
int pageIndex = 1;
int totalRecord = groupList.Count;
int pageCount = (totalRecord + pageSize - 1) / pageSize;
while (pageCount >= pageIndex)
{
batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString);
batchInsetrSql.AppendFormat("SELECT * FROM (");
int i = 0;
foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList())
{
var isFirst = i == 0;
if (!isFirst) batchInsetrSql.Append(SqlTemplateBatchUnion);
batchInsetrSql.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(SqlTemplateBatchSelect, base.GetDbColumn(it, FormatValue(it.Value)), Builder.GetTranslationColumnName(it.DbColumnName)))) + " from dual");
++i;
}
pageIndex++;
batchInsetrSql.Append(") temp1\r\n;\r\n");
}
return batchInsetrSql.ToString();// + " GETID ";
}
}
public override object FormatValue(object value)
{
var n = "";
if (value == null) return "NULL";
var type = UtilMethods.GetUnderType(value.GetType());
if (type == UtilConstants.DateType) return GetDateTimeString(value);
else if (value is DateTimeOffset) return GetDateTimeOffsetString(value);
else if (type == UtilConstants.ByteArrayType)
{
string bytesString = "0x" + BitConverter.ToString((byte[])value).Replace("-", "");
return bytesString;
}
else if (type.IsEnum())
{
if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) return value.ToSqlValue();
else return Convert.ToInt64(value);
}
else if (type == UtilConstants.BoolType) return value.ObjToBool() ? "1" : "0";
else return n + "'" + value + "'";
}
private object GetDateTimeOffsetString(object value)
{
var date = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)value);
if (date < UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig))
date = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig);
return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
}
private object GetDateTimeString(object value)
{
var date = value.ObjToDate();
if (date < UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig))
date = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig);
return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
}
}
}

View File

@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SqlSugar.Xugu
{
public class XuguQueryBuilder: QueryBuilder
{
#region Sql Template
/* SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 0,10 */
public override string PageTempalte { get; }= "SELECT {0} FROM {1} {2} {3} {4} LIMIT {5},{6}";
public override string DefaultOrderByTemplate { get; } = "ORDER BY SYSDATE ";
#endregion
#region Common Methods
public override bool IsComplexModel(string sql)=> Regex.IsMatch(sql, @"AS \`\w+\.\w+\`") || Regex.IsMatch(sql, @"AS \`\w+\.\w+\.\w+\`");
public override string ToSqlString()
{
base.AppendFilter();
string oldOrderValue = this.OrderByValue;
string result = null;
sql = new StringBuilder();
sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString);
if (IsCount) { return sql.ToString(); }
if (Skip != null && Take == null)
{
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString, Skip.ObjToInt(), long.MaxValue);
}
else if (Skip == null && Take != null)
{
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, 0, Take.ObjToInt());
}
else if (Skip != null && Take != null)
{
if (Skip == 0 && Take == 1 && this.OrderByValue == "ORDER BY SYSDATE ") this.OrderByValue = null;
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt() > 0 ? Skip.ObjToInt() : 0, Take);
}
else
{
result = sql.ToString();
}
this.OrderByValue = oldOrderValue;
result = GetSqlQuerySql(result);
if (result.IndexOf("-- No table") > 0) return "-- No table";
if (TranLock != null) result = result + TranLock;
return result;
}
private string ToCountSqlString()
{
//base.AppendFilter();
string oldOrderValue = this.OrderByValue;
string result = null;
sql = new StringBuilder();
sql.AppendFormat(SqlTemplate, "COUNT(*)", GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString);
if (IsCount)
{
if (sql.ToString().Contains("-- No table")) return "-- No table";
return sql.ToString();
}
if (Skip != null && Take == null)
{
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString, Skip.ObjToInt(), long.MaxValue);
}
else if (Skip == null && Take != null)
{
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, 0, Take.ObjToInt());
}
else if (Skip != null && Take != null)
{
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt() > 0 ? Skip.ObjToInt() : 0, Take);
}
else
{
result = sql.ToString();
}
this.OrderByValue = oldOrderValue;
return result;
}
public override string ToCountSql(string sql)
{
if (this.GroupByValue.HasValue() || this.IsDistinct) return base.ToCountSql(sql);
else return ToCountSqlString();
}
#endregion
#region Get SQL Partial
public override string GetSelectValue
{
get
{
string result = string.Empty;
if (this.SelectValue == null || this.SelectValue is string) result = GetSelectValueByString();
else result = GetSelectValueByExpression();
if (this.SelectType == ResolveExpressType.SelectMultiple)
this.SelectCacheKey = this.SelectCacheKey + string.Join("-", this.JoinQueryInfos.Select(it => it.TableName));
if (IsDistinct) result = " DISTINCT " + result;
if (this.SubToListParameters != null && this.SubToListParameters.Any()) result = SubToListMethod(result);
return result;
}
}
#endregion
}
}

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SqlSugar.Xugu
{
public class XuguUpdateBuilder : UpdateBuilder
{
protected override string TomultipleSqlString(List<IGrouping<int, DbColumnInfo>> groupList)
{
if (groupList == null || groupList.Count == 0) return "SELECT 0 FROM DUAL";
StringBuilder sb = new StringBuilder();
int i = 0;
sb.AppendLine(string.Join(UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", ""), groupList.Select(t =>
{
var updateTable = string.Format("UPDATE {0} SET ", base.GetTableNameStringNoWith);
var setValues = string.Join(",", t.Where(s => !s.IsPrimarykey).Select(m => GetOracleUpdateColums(i, m, false)).ToArray());
var pkList = t.Where(s => s.IsPrimarykey).ToList();
List<string> whereList = new List<string>();
foreach (var item in pkList)
{
var isFirst = pkList.First() == item;
var whereString = "";
whereString += GetOracleUpdateColums(i, item, true);
whereList.Add(whereString);
}
i++;
return string.Format("{0} {1} WHERE {2} ", updateTable, setValues, string.Join(" AND", whereList));
}).ToArray()));
return sb.ToString();
}
private object GetValue(DbColumnInfo it)=> FormatValue(it.Value);
private string GetOracleUpdateColums(int i, DbColumnInfo m, bool iswhere)=> string.Format("{0}={1}", m.DbColumnName, base.GetDbColumn(m, FormatValue(i, m.DbColumnName, m.Value, iswhere)));
public object FormatValue(int i, string name, object value, bool iswhere)
{
if (value == null) return "NULL";
else
{
var type = UtilMethods.GetUnderType(value.GetType());
if (type == UtilConstants.DateType && iswhere == false)
{
var date = value.ObjToDate();
if (date < UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig))
date = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig);
if (this.Context.CurrentConnectionConfig?.MoreSettings?.DisableMillisecond == true)
return "'" + date.ToString("yyyy-MM-dd HH:mm:ss") + "'";
else
return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
}
else if (type == UtilConstants.DateType && iswhere)
{
var parameterName = this.Builder.SqlParameterKeyWord + name + i;
this.Parameters.Add(new SugarParameter(parameterName, value));
return parameterName;
}
else if (type.IsEnum())
{
if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) return value.ToSqlValue();
else return Convert.ToInt64(value);
}
else if (type == UtilConstants.ByteArrayType)
{
var parameterName = this.Builder.SqlParameterKeyWord + name + i;
this.Parameters.Add(new SugarParameter(parameterName, value));
return parameterName;
}
else if (value is int || value is long || value is short || value is short || value is byte) return value;
else if (value is bool) return value.ObjToString().ToLower();
else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) return "'" + value.ToString().ToSqlFilter() + "'";
else return "'" + value.ToString() + "'";
}
}
}
}