diff --git a/PetaPoco/Core/DatabaseProvider.cs b/PetaPoco/Core/DatabaseProvider.cs index ef175143..de9bc221 100644 --- a/PetaPoco/Core/DatabaseProvider.cs +++ b/PetaPoco/Core/DatabaseProvider.cs @@ -209,6 +209,8 @@ internal static IProvider Resolve(Type type, bool allowDefault, string connectio return Singleton.Instance; if (typeName.StartsWith("FbConnection") || typeName.EndsWith("FirebirdClientFactory")) return Singleton.Instance; + if (typeName.StartsWith("Teradata")) + return Singleton.Instance; if (typeName.IndexOf("OleDb", StringComparison.InvariantCultureIgnoreCase) >= 0 && (connectionString.IndexOf("Jet.OLEDB", StringComparison.InvariantCultureIgnoreCase) > 0 || connectionString.IndexOf("ACE.OLEDB", StringComparison.InvariantCultureIgnoreCase) > 0)) { @@ -248,6 +250,8 @@ internal static IProvider Resolve(string providerName, bool allowDefault, string if (providerName.IndexOf("Firebird", StringComparison.InvariantCultureIgnoreCase) >= 0 || providerName.IndexOf("FbConnection", StringComparison.InvariantCultureIgnoreCase) >= 0) return Singleton.Instance; + if (providerName.IndexOf("Teradata", StringComparison.InvariantCultureIgnoreCase) >= 0) + return Singleton.Instance; if (providerName.IndexOf("OleDb", StringComparison.InvariantCultureIgnoreCase) >= 0 && (connectionString.IndexOf("Jet.OLEDB", StringComparison.InvariantCultureIgnoreCase) > 0 || connectionString.IndexOf("ACE.OLEDB", StringComparison.InvariantCultureIgnoreCase) > 0)) { @@ -280,4 +284,4 @@ internal static DbProviderFactory Unwrap(DbProviderFactory factory) return unwrapped == null ? factory : Unwrap(unwrapped); } } -} \ No newline at end of file +} diff --git a/PetaPoco/PetaPoco.csproj b/PetaPoco/PetaPoco.csproj index a5455363..c91071a7 100644 --- a/PetaPoco/PetaPoco.csproj +++ b/PetaPoco/PetaPoco.csproj @@ -79,6 +79,7 @@ + @@ -134,4 +135,4 @@ --> - \ No newline at end of file + diff --git a/PetaPoco/Providers/TeradataProvider.cs b/PetaPoco/Providers/TeradataProvider.cs new file mode 100644 index 00000000..48e5f66e --- /dev/null +++ b/PetaPoco/Providers/TeradataProvider.cs @@ -0,0 +1,55 @@ +using System; +using System.Data; +using System.Data.Common; +using PetaPoco.Core; +using PetaPoco.Internal; +using PetaPoco.Utilities; +using System.Text.RegularExpressions; +using System.Linq; + +namespace PetaPoco.Providers +{ + public class TeradataDatabaseProvider : DatabaseProvider + { + public override DbProviderFactory GetFactory() + { + return DbProviderFactories.GetFactory("Teradata.Client.Provider"); + } + + private static readonly Regex simpleRegexOrderBy = new Regex(@"\bORDER\s+BY\s+", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); + + public override string BuildPageQuery(long skip, long take, SQLParts parts, ref object[] args) + { + var helper = (PagingHelper)PagingUtility; + // when the query does not contain an "order by", it is very slow + if (simpleRegexOrderBy.IsMatch(parts.SqlSelectRemoved)) + { + parts.SqlSelectRemoved = helper.RegexOrderBy.Replace(parts.SqlSelectRemoved, "", 1); + } + if (helper.RegexDistinct.IsMatch(parts.SqlSelectRemoved)) + { + parts.SqlSelectRemoved = "peta_inner.* FROM (SELECT " + parts.SqlSelectRemoved + ") peta_inner"; + } + var sqlPage = string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER ({0}) peta_rn, {1}) peta_paged WHERE peta_rn > @{2} AND peta_rn <= @{3}", parts.SqlOrderBy ?? "ORDER BY (SELECT NULL)", parts.SqlSelectRemoved, args.Length, args.Length + 1); + args = args.Concat(new object[] { skip, skip + take }).ToArray(); + return sqlPage; + } + + public override object ExecuteInsert(Database db, System.Data.IDbCommand cmd, string primaryKeyName) + { + return db.ExecuteScalarHelper(cmd); + } + + public override string GetExistsSql() + { + return "IF EXISTS (SELECT 1 FROM {0} WHERE {1}) SELECT 1 ELSE SELECT 0"; + } + + public override string GetInsertOutputClause(string primaryKeyName) + { + return String.Format(" OUTPUT INSERTED.[{0}]", primaryKeyName); + } + } + + +}