Mercurial > pub > bltoolkit
diff Source/Data/DataProvider/Interpreters/OracleDataProviderInterpreter.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/DataProvider/Interpreters/OracleDataProviderInterpreter.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using BLToolkit.Data.Sql.SqlProvider; +using BLToolkit.DataAccess; +using BLToolkit.Mapping; + +namespace BLToolkit.Data.DataProvider.Interpreters +{ + public class OracleDataProviderInterpreter : DataProviderInterpreterBase + { + public override void SetParameterValue(IDbDataParameter parameter, object value) + { + if (value is TimeSpan) + { + parameter.Value = ((TimeSpan)value).ToString(); + } + else + base.SetParameterValue(parameter, value); + } + + public override List<string> GetInsertBatchSqlList<T>( + string insertText, + IEnumerable<T> collection, + MemberMapper[] members, + int maxBatchSize, + bool withIdentity) + { + //return GetInsertBatchSqlListWithInsertAll(insertText, collection, members, maxBatchSize); + return GetInsertBatchSqlListUnionAll(insertText, collection, members, maxBatchSize, withIdentity); + } + + private List<string> GetInsertBatchSqlListUnionAll<T>( + string insertText, + IEnumerable<T> collection, + MemberMapper[] members, + int maxBatchSize, + bool withIdentity) + { + var sp = new OracleSqlProvider(); + var n = 0; + var sqlList = new List<string>(); + + var indexValuesWord = insertText.IndexOf(" VALUES (", StringComparison.Ordinal); + var initQuery = insertText.Substring(0, indexValuesWord) + Environment.NewLine; + var valuesQuery = insertText.Substring(indexValuesWord + 9); + var indexEndValuesQuery = valuesQuery.IndexOf(")"); + valuesQuery = valuesQuery.Substring(0, indexEndValuesQuery) + .Replace("\r", "") + .Replace("\n", "") + .Replace("\t", ""); + + // 1 = Number of primary keys generated by sequence + var valuesWihtoutSequence = withIdentity ? valuesQuery.Substring(valuesQuery.IndexOf(",") + 1) : valuesQuery; + + var sb = new StringBuilder(initQuery); + sb.Append(" SELECT "); + sb.AppendFormat(valuesQuery, members.Select(m => m.Name).ToArray()); + sb.AppendLine(" FROM ("); + + initQuery = sb.ToString(); + + sb = new StringBuilder(initQuery); + bool isFirstValues = true; + + foreach (var item in collection) + { + if (!isFirstValues) + sb.AppendLine(" UNION ALL "); + + sb.Append("SELECT "); + + var values = new List<object>(); + foreach (var member in members) + { + var sbItem = new StringBuilder(); + + var value = member.GetValue(item); + + if (value is DateTime?) + value = ((DateTime?)value).Value; + + sp.BuildValue(sbItem, value); + + values.Add(sbItem + " " + member.Name); + } + + sb.AppendFormat(valuesWihtoutSequence, values.ToArray()); + sb.Append(" FROM DUAL"); + + isFirstValues = false; + + n++; + if (n > maxBatchSize) + { + sb.Append(")"); + sqlList.Add(sb.ToString()); + sb = new StringBuilder(initQuery); + isFirstValues = true; + n = 0; + } + } + + if (n > 0) + { + sb.Append(")"); + sqlList.Add(sb.ToString()); + } + return sqlList; + } + + private List<string> GetInsertBatchSqlListWithInsertAll<T>( + string insertText, + IEnumerable<T> collection, + MemberMapper[] members, + int maxBatchSize) + { + var sb = new StringBuilder(); + var sp = new OracleSqlProvider(); + var n = 0; + var sqlList = new List<string>(); + + foreach (var item in collection) + { + if (sb.Length == 0) + sb.AppendLine("INSERT ALL"); + + string strItem = "\t" + insertText + .Replace("INSERT INTO", "INTO") + .Replace("\r", "") + .Replace("\n", "") + .Replace("\t", " ") + .Replace("( ", "("); + + var values = new List<object>(); + foreach (var member in members) + { + var sbItem = new StringBuilder(); + + var keyGenerator = member.MapMemberInfo.KeyGenerator as SequenceKeyGenerator; + if (keyGenerator != null) + { + values.Add(NextSequenceQuery(keyGenerator.Sequence)); + } + else + { + var value = member.GetValue(item); + + if (value is DateTime?) + value = ((DateTime?)value).Value; + + sp.BuildValue(sbItem, value); + + values.Add(sbItem.ToString()); + } + } + + sb.AppendFormat(strItem, values.ToArray()); + sb.AppendLine(); + + n++; + + if (n >= maxBatchSize) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + sqlList.Add(sql); + + n = 0; + sb.Length = 0; + } + } + + if (n > 0) + { + sb.AppendLine("SELECT * FROM dual"); + + var sql = sb.ToString(); + sqlList.Add(sql); + } + + return sqlList; + } + + public override string GetSequenceQuery(string sequenceName) + { + return string.Format("SELECT {0}.NEXTVAL FROM DUAL", sequenceName); + } + + public override string NextSequenceQuery(string sequenceName) + { + return string.Format("{0}.NEXTVAL", sequenceName); + } + + public override string GetReturningInto(string columnName) + { + return string.Format("returning {0} into :IDENTITY_PARAMETER", columnName); + } + } +} \ No newline at end of file