Files
FreeSql/Providers/FreeSql.Provider.GBase/GBaseUtils.cs
2025-12-02 16:13:05 +08:00

152 lines
7.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FreeSql.Internal;
using FreeSql.Internal.Model;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Odbc;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Text;
namespace FreeSql.GBase
{
class GBaseUtils : CommonUtils
{
public GBaseUtils(IFreeSql orm) : base(orm)
{
}
public override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, ColumnInfo col, Type type, object value)
{
if (string.IsNullOrEmpty(parameterName)) parameterName = "?";
var ret = new OdbcParameter { ParameterName = "?", Value = value };
var dbtype = (OdbcType?)_orm.CodeFirst.GetDbInfo(type)?.type;
if (col != null)
{
var dbtype2 = (OdbcType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize });
switch (dbtype2)
{
case OdbcType.VarBinary:
break;
default:
dbtype = dbtype2;
//if (col.DbSize != 0) ret.Size = col.DbSize;
if (col.DbPrecision != 0) ret.Precision = col.DbPrecision;
if (col.DbScale != 0) ret.Scale = col.DbScale;
break;
}
}
if (dbtype != null) ret.OdbcType = dbtype.Value;
_params?.Add(ret);
return ret;
}
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
Utils.GetDbParamtersByObject<DbParameter>("*", obj, "?", (name, type, value) =>
{
var ret = new OdbcParameter { ParameterName = $"{name}" };
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
if (tp != null) ret.OdbcType = (OdbcType)tp.Value;
else
{
ret.OdbcType = OdbcType.VarChar;
ret.Size = 8000;
}
ret.Value = value;
return ret;
});
public override string FormatSql(string sql, params object[] args) => sql?.FormatGBase(args);
public override string QuoteSqlNameAdapter(params string[] name)
{
if (name.Length == 1)
{
var nametrim = name[0].Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return nametrim;
}
return string.Join(":", name);
}
public override string TrimQuoteSqlName(string name)
{
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return nametrim;
}
public override string[] SplitTableName(string name) => name?.Split(new char[] { ':' }, 1);
public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
readonly static Regex _regDateTime = new Regex(@"^'(\d{4,4}\-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2})(\.\d+)?'$", RegexOptions.Compiled);
public override string IsNull(string sql, object value)
{
if (value is string valueStr)
{
var match = _regDateTime.Match(valueStr);
if (match.Success)
{
if (string.IsNullOrEmpty(match.Groups[2].Value)) value = $"DATETIME({match.Groups[1].Value}) YEAR TO SECOND";
else value = $"DATETIME({match.Groups[1].Value}{match.Groups[2].Value}) YEAR TO FRACTION({(match.Groups[2].Value.Length - 1)})";
}
}
return $"nvl({sql}, {value})";
}
public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";
public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left},{right})";
public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left}/{right})";
public override string Now => "current";
public override string NowUtc => "current";
public override string QuoteWriteParamterAdapter(Type type, string paramterName) => paramterName;
protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) => columnName;
public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, string specialParamFlag, ColumnInfo col, Type type, object value)
{
if (value == null) return "NULL";
if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value);
if (type == typeof(byte[]))
{
var pam = AppendParamter(specialParams, "", null, type, value);
return pam.ParameterName;
}
if (type == typeof(DateTime))
{
if (Utils.TypeHandlers.TryGetValue(typeof(DateTime), out var typeHandler)) return FormatSql("{0}", typeHandler.Serialize(value), 1);
if (col?.DbPrecision > 0)
return string.Concat("'", ((DateTime)value).ToString($"yyyy-MM-dd HH:mm:ss.{"f".PadRight(col.DbPrecision, 'f')}"), "'");
return string.Concat("'", ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"), "'");
}
if (type == typeof(DateTime?))
{
if (Utils.TypeHandlers.TryGetValue(typeof(DateTime?), out var typeHandler)) return FormatSql("{0}", typeHandler.Serialize(value), 1);
if (col?.DbPrecision > 0)
return string.Concat("'", ((DateTime)value).ToString($"yyyy-MM-dd HH:mm:ss.{"f".PadRight(col.DbPrecision, 'f')}"), "'");
return string.Concat("'", ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"), "'");
}
if (type == typeof(string))
{
var str = (string)value;
// TEXT和byte字段类型无法用insert直接写入,CLOB需启用Oracle后可直接insert; 参考https://www.gbase.cn/community/post/4863
var isText = (col?.Attribute?.DbType?.IndexOf("TEXT", StringComparison.OrdinalIgnoreCase) ?? -1) >= 0
|| string.Equals(col?.DbTypeText, "text", StringComparison.CurrentCultureIgnoreCase);
if (isText)
{
var pam = AppendParamter(specialParams, "", col, typeof(byte[]), value);
((OdbcParameter)pam).OdbcType = OdbcType.VarBinary;
pam.Value = value == null ? (object)DBNull.Value : (object)Encoding.UTF8.GetBytes(str ?? "");
return pam.ParameterName;
}
// if (str?.Length > 8000) // 长字符串GBase8s不能以text或varBinary格式写入反而直接写入无异常
// {
// var pam = AppendParamter(specialParams, "", col, type, value);
// ((OdbcParameter)pam).OdbcType = OdbcType.Text;
// return pam.ParameterName;
// }
}
return FormatSql("{0}", value, 1);
}
}
}