Updated petapoco to 4.0.3

pull/6/head
kay.one 13 years ago
parent 06eeea6a5c
commit 5a4e8330b2

@ -10,8 +10,6 @@ using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository; using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using PetaPoco;
using TvdbLib.Data;
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
namespace NzbDrone.Core.Test namespace NzbDrone.Core.Test

@ -85,16 +85,17 @@ namespace NzbDrone.Core.Test
} }
//assert //assert
seasonsNumbers.Should().HaveCount(8); seasonsNumbers.Should().HaveCount(7);
seasons[1].Should().HaveCount(23); seasons[1].Should().HaveCount(23);
seasons[2].Should().HaveCount(19); seasons[2].Should().HaveCount(19);
seasons[3].Should().HaveCount(16); seasons[3].Should().HaveCount(16);
seasons[4].Should().HaveCount(20); seasons[4].Should().HaveCount(20);
seasons[5].Should().HaveCount(18); seasons[5].Should().HaveCount(18);
seasons[6].Should().HaveCount(19);
foreach (var season in seasons) foreach (var season in seasons)
{ {
season.Value.Should().OnlyHaveUniqueItems(); season.Value.Should().OnlyHaveUniqueItems("Season {0}", season.Key);
} }
//Make sure no episode number is skipped //Make sure no episode number is skipped

@ -1,17 +1,18 @@
using System; using System;
using System.Reflection;
using PetaPoco; using PetaPoco;
namespace NzbDrone.Core.Datastore namespace NzbDrone.Core.Datastore
{ {
public class CustomeMapper : DefaultMapper public class CustomeMapper : DefaultMapper
{ {
public override Func<object, object> GetFromDbConverter(DestinationInfo destinationInfo, Type sourceType) public override Func<object, object> GetFromDbConverter(Type destinationType, Type sourceType)
{ {
if ((sourceType == typeof(Int32) || sourceType == typeof(Int64)) && destinationInfo.Type.IsGenericType && destinationInfo.Type.GetGenericTypeDefinition() == typeof(Nullable<>)) if ((sourceType == typeof(Int32) || sourceType == typeof(Int64)) && destinationType.IsGenericType && destinationType.GetGenericTypeDefinition() == typeof(Nullable<>))
{ {
// If it is NULLABLE, then get the underlying type. eg if "Nullable<int>" then this will return just "int" // If it is NULLABLE, then get the underlying type. eg if "Nullable<int>" then this will return just "int"
Type genericArgument = destinationInfo.Type.GetGenericArguments()[0]; Type genericArgument = destinationType.GetGenericArguments()[0];
if (genericArgument == typeof(DayOfWeek)) if (genericArgument == typeof(DayOfWeek))
{ {
return delegate(object s) return delegate(object s)
@ -30,7 +31,14 @@ namespace NzbDrone.Core.Datastore
}; };
} }
return base.GetFromDbConverter(destinationInfo, sourceType); return base.GetFromDbConverter(destinationType, sourceType);
}
public override Func<object, object> GetFromDbConverter(PropertyInfo propertyInfo, Type sourceType)
{
return GetFromDbConverter(propertyInfo.PropertyType, sourceType);
} }
} }
} }

@ -1,4 +1,4 @@
/* PetaPoco v4.0.2 - A Tiny ORMish thing for your POCO's. /* PetaPoco v4.0.3 - A Tiny ORMish thing for your POCO's.
* Copyright © 2011 Topten Software. All Rights Reserved. * Copyright © 2011 Topten Software. All Rights Reserved.
* *
* Apache License 2.0 - http://www.toptensoftware.com/petapoco/license * Apache License 2.0 - http://www.toptensoftware.com/petapoco/license
@ -13,18 +13,16 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration; using System.Configuration;
using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Diagnostics; using System.Data;
using System.Linq; using System.Text.RegularExpressions;
using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Text; using System.Linq.Expressions;
using System.Text.RegularExpressions;
using System.Threading;
using MvcMiniProfiler;
namespace PetaPoco namespace PetaPoco
{ {
@ -91,7 +89,7 @@ namespace PetaPoco
[AttributeUsage(AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Property)]
public class VersionColumnAttribute : ColumnAttribute public class VersionColumnAttribute : ColumnAttribute
{ {
public VersionColumnAttribute() { } public VersionColumnAttribute() {}
public VersionColumnAttribute(string name) : base(name) { } public VersionColumnAttribute(string name) : base(name) { }
} }
@ -125,23 +123,29 @@ namespace PetaPoco
public string SequenceName { get; set; } public string SequenceName { get; set; }
} }
// Optionally provide and implementation of this to Database.Mapper // Optionally provide an implementation of this to Database.Mapper
public interface IMapper public interface IMapper
{ {
void GetTableInfo(Type t, TableInfo ti); void GetTableInfo(Type t, TableInfo ti);
bool MapPropertyToColumn(PropertyInfo pi, ref string columnName, ref bool resultColumn); bool MapPropertyToColumn(PropertyInfo pi, ref string columnName, ref bool resultColumn);
Func<object, object> GetFromDbConverter(DestinationInfo destinationInfo, Type SourceType); Func<object, object> GetFromDbConverter(PropertyInfo pi, Type sourceType);
Func<object, object> GetToDbConverter(Type SourceType); Func<object, object> GetToDbConverter(Type SourceType);
} }
public class DefaultMapper : IMapper // This will be merged with IMapper in the next major version
public interface IMapper2 : IMapper
{
Func<object, object> GetFromDbConverter(Type DestType, Type SourceType);
}
public class DefaultMapper : IMapper2
{ {
public virtual void GetTableInfo(Type t, TableInfo ti) { } public virtual void GetTableInfo(Type t, TableInfo ti) { }
public virtual bool MapPropertyToColumn(PropertyInfo pi, ref string columnName, ref bool resultColumn) public virtual bool MapPropertyToColumn(PropertyInfo pi, ref string columnName, ref bool resultColumn)
{ {
return true; return true;
} }
public virtual Func<object, object> GetFromDbConverter(DestinationInfo destinationInfo, Type SourceType) public virtual Func<object, object> GetFromDbConverter(PropertyInfo pi, Type sourceType)
{ {
return null; return null;
} }
@ -149,24 +153,28 @@ namespace PetaPoco
{ {
return null; return null;
} }
} public virtual Func<object, object> GetFromDbConverter(Type DestType, Type SourceType)
public class DestinationInfo
{
public DestinationInfo(Type type)
{ {
Type = type; return null;
} }
public DestinationInfo(PropertyInfo propertyInfo)
{
PropertyInfo = propertyInfo;
Type = propertyInfo.PropertyType;
} }
public PropertyInfo PropertyInfo { get; private set; } //public class DestinationInfo
public Type Type { get; private set; } //{
} // public DestinationInfo(Type type)
// {
// Type = type;
// }
// public DestinationInfo(PropertyInfo propertyInfo)
// {
// PropertyInfo = propertyInfo;
// Type = propertyInfo.PropertyType;
// }
// public PropertyInfo PropertyInfo { get; private set; }
// public Type Type { get; private set; }
//}
public interface IDatabaseQuery public interface IDatabaseQuery
{ {
@ -240,6 +248,10 @@ namespace PetaPoco
object Insert(object poco); object Insert(object poco);
int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue); int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue);
int Update(string tableName, string primaryKeyName, object poco); int Update(string tableName, string primaryKeyName, object poco);
int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable<string> columns);
int Update(string tableName, string primaryKeyName, object poco, IEnumerable<string> columns);
int Update(object poco, IEnumerable<string> columns);
int Update(object poco, object primaryKeyValue, IEnumerable<string> columns);
int Update(object poco); int Update(object poco);
int Update(object poco, object primaryKeyValue); int Update(object poco, object primaryKeyValue);
int Update<T>(string sql, params object[] args); int Update<T>(string sql, params object[] args);
@ -317,7 +329,7 @@ namespace PetaPoco
Oracle, Oracle,
SQLite SQLite
} }
DBType _dbType = DBType.SqlServerCE; DBType _dbType = DBType.SqlServer;
// Common initialization // Common initialization
private void CommonConstruct() private void CommonConstruct()
@ -329,7 +341,7 @@ namespace PetaPoco
if (_providerName != null) if (_providerName != null)
_factory = DbProviderFactories.GetFactory(_providerName); _factory = DbProviderFactories.GetFactory(_providerName);
string dbtype = (_factory == null ? _sharedConnection.GetType() : _factory.GetType()).Name; string dbtype = (_factory==null ? _sharedConnection.GetType() : _factory.GetType()).Name;
if (dbtype.StartsWith("MySql")) _dbType = DBType.MySql; if (dbtype.StartsWith("MySql")) _dbType = DBType.MySql;
else if (dbtype.StartsWith("SqlCe")) _dbType = DBType.SqlServerCE; else if (dbtype.StartsWith("SqlCe")) _dbType = DBType.SqlServerCE;
else if (dbtype.StartsWith("Npgsql")) _dbType = DBType.PostgreSQL; else if (dbtype.StartsWith("Npgsql")) _dbType = DBType.PostgreSQL;
@ -355,8 +367,6 @@ namespace PetaPoco
// Open a connection (can be nested) // Open a connection (can be nested)
public void OpenSharedConnection() public void OpenSharedConnection()
{
using (MvcMiniProfiler.MiniProfiler.StepStatic("OpenSharedConnection"))
{ {
if (_sharedConnectionDepth == 0) if (_sharedConnectionDepth == 0)
{ {
@ -364,16 +374,18 @@ namespace PetaPoco
_sharedConnection.ConnectionString = _connectionString; _sharedConnection.ConnectionString = _connectionString;
_sharedConnection.Open(); _sharedConnection.Open();
_sharedConnection = OnConnectionOpened(_sharedConnection);
if (KeepConnectionAlive) if (KeepConnectionAlive)
_sharedConnectionDepth++; // Make sure you call Dispose _sharedConnectionDepth++; // Make sure you call Dispose
} }
_sharedConnectionDepth++; _sharedConnectionDepth++;
} }
}
/// <summary> /// <summary>
/// Close a previously opened connection /// Close a previously opened connection
/// </summary> /// </summary>
// Close a previously opened connection
public void CloseSharedConnection() public void CloseSharedConnection()
{ {
if (_sharedConnectionDepth > 0) if (_sharedConnectionDepth > 0)
@ -381,6 +393,7 @@ namespace PetaPoco
_sharedConnectionDepth--; _sharedConnectionDepth--;
if (_sharedConnectionDepth == 0) if (_sharedConnectionDepth == 0)
{ {
OnConnectionClosing(_sharedConnection);
_sharedConnection.Dispose(); _sharedConnection.Dispose();
_sharedConnection = null; _sharedConnection = null;
} }
@ -490,20 +503,32 @@ namespace PetaPoco
} }
// Expand collections to parameter lists // Expand collections to parameter lists
if ((arg_val as IEnumerable) != null && if ((arg_val as System.Collections.IEnumerable) != null &&
(arg_val as string) == null && (arg_val as string) == null &&
(arg_val as byte[]) == null) (arg_val as byte[]) == null)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
foreach (var i in arg_val as IEnumerable) foreach (var i in arg_val as System.Collections.IEnumerable)
{
var indexOfExistingValue = args_dest.IndexOf(i);
if (indexOfExistingValue >= 0)
{ {
sb.Append((sb.Length == 0 ? "@" : ",@") + args_dest.Count.ToString()); sb.Append((sb.Length == 0 ? "@" : ",@") + indexOfExistingValue);
}
else
{
sb.Append((sb.Length == 0 ? "@" : ",@") + args_dest.Count);
args_dest.Add(i); args_dest.Add(i);
}
} }
return sb.ToString(); return sb.ToString();
} }
else else
{ {
var indexOfExistingValue = args_dest.IndexOf(arg_val);
if (indexOfExistingValue >= 0)
return "@" + indexOfExistingValue;
args_dest.Add(arg_val); args_dest.Add(arg_val);
return "@" + (args_dest.Count - 1).ToString(); return "@" + (args_dest.Count - 1).ToString();
} }
@ -515,10 +540,10 @@ namespace PetaPoco
void AddParam(IDbCommand cmd, object item, string ParameterPrefix) void AddParam(IDbCommand cmd, object item, string ParameterPrefix)
{ {
// Convert value to from poco type to db type // Convert value to from poco type to db type
if (Mapper != null && item != null) if (Database.Mapper != null && item!=null)
{ {
var fn = Mapper.GetToDbConverter(item.GetType()); var fn = Database.Mapper.GetToDbConverter(item.GetType());
if (fn != null) if (fn!=null)
item = fn(item); item = fn(item);
} }
@ -588,18 +613,15 @@ namespace PetaPoco
// Create a command // Create a command
static Regex rxParamsPrefix = new Regex(@"(?<!@)@\w+", RegexOptions.Compiled); static Regex rxParamsPrefix = new Regex(@"(?<!@)@\w+", RegexOptions.Compiled);
public IDbCommand CreateCommand(IDbConnection connection, Sql sqlStatement) IDbCommand CreateCommand(IDbConnection connection, string sql, params object[] args)
{ {
var sql = sqlStatement.SQL;
var args = sqlStatement.Arguments;
// Perform parameter prefix replacements // Perform parameter prefix replacements
if (_paramPrefix != "@") if (_paramPrefix != "@")
sql = rxParamsPrefix.Replace(sql, m => _paramPrefix + m.Value.Substring(1)); sql = rxParamsPrefix.Replace(sql, m => _paramPrefix + m.Value.Substring(1));
sql = sql.Replace("@@", "@"); // <- double @@ escapes a single @ sql = sql.Replace("@@", "@"); // <- double @@ escapes a single @
// Create the command and add parameters // Create the command and add parameters
IDbCommand cmd = _factory == null ? connection.CreateCommand() : _factory.CreateCommand(); IDbCommand cmd = connection.CreateCommand();
cmd.Connection = connection; cmd.Connection = connection;
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.Transaction = _transaction; cmd.Transaction = _transaction;
@ -621,20 +643,22 @@ namespace PetaPoco
} }
// Create a command // Create a command
IDbCommand CreateCommand(IDbConnection connection, string sql, params object[] args) //IDbCommand CreateCommand(IDbConnection connection, string sql, params object[] args)
{ //{
var sqlStatement = new Sql(sql, args); // var sqlStatement = new Sql(sql, args);
return CreateCommand(connection, sqlStatement); // return CreateCommand(connection, sqlStatement);
} //}
// Override this to log/capture exceptions // Override this to log/capture exceptions
public virtual void OnException(Exception x) public virtual void OnException(Exception x)
{ {
Debug.WriteLine(x.ToString()); System.Diagnostics.Debug.WriteLine(x.ToString());
Debug.WriteLine(LastCommand); System.Diagnostics.Debug.WriteLine(LastCommand);
} }
// Override this to log commands, or modify command before execution // Override this to log commands, or modify command before execution
public virtual IDbConnection OnConnectionOpened(IDbConnection conn) { return conn; }
public virtual void OnConnectionClosing(IDbConnection conn) { }
public virtual void OnExecutingCommand(IDbCommand cmd) { } public virtual void OnExecutingCommand(IDbCommand cmd) { }
public virtual void OnExecutedCommand(IDbCommand cmd) { } public virtual void OnExecutedCommand(IDbCommand cmd) { }
@ -644,16 +668,17 @@ namespace PetaPoco
return Execute(new Sql(sql, args)); return Execute(new Sql(sql, args));
} }
public int Execute(Sql sql) public int Execute(Sql Sql)
{
using (MiniProfiler.StepStatic("Peta Execute SQL"))
{ {
var sql = Sql.SQL;
var args = Sql.Arguments;
try try
{ {
OpenSharedConnection(); OpenSharedConnection();
try try
{ {
using (var cmd = CreateCommand(_sharedConnection, sql)) using (var cmd = CreateCommand(_sharedConnection, sql, args))
{ {
var result = cmd.ExecuteNonQuery(); var result = cmd.ExecuteNonQuery();
OnExecutedCommand(cmd); OnExecutedCommand(cmd);
@ -671,7 +696,6 @@ namespace PetaPoco
throw; throw;
} }
} }
}
// Execute and cast a scalar property // Execute and cast a scalar property
public T ExecuteScalar<T>(string sql, params object[] args) public T ExecuteScalar<T>(string sql, params object[] args)
@ -679,16 +703,17 @@ namespace PetaPoco
return ExecuteScalar<T>(new Sql(sql, args)); return ExecuteScalar<T>(new Sql(sql, args));
} }
public T ExecuteScalar<T>(Sql sql) public T ExecuteScalar<T>(Sql Sql)
{
using (MiniProfiler.StepStatic("Peta ExecuteScalar<T>"))
{ {
var sql = Sql.SQL;
var args = Sql.Arguments;
try try
{ {
OpenSharedConnection(); OpenSharedConnection();
try try
{ {
using (var cmd = CreateCommand(_sharedConnection, sql)) using (var cmd = CreateCommand(_sharedConnection, sql, args))
{ {
object val = cmd.ExecuteScalar(); object val = cmd.ExecuteScalar();
OnExecutedCommand(cmd); OnExecutedCommand(cmd);
@ -706,10 +731,9 @@ namespace PetaPoco
throw; throw;
} }
} }
}
Regex rxSelect = new Regex(@"\A\s*(SELECT|EXECUTE|CALL)\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline); static Regex rxSelect = new Regex(@"\A\s*(SELECT|EXECUTE|CALL)\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
Regex rxFrom = new Regex(@"\A\s*FROM\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline); static Regex rxFrom = new Regex(@"\A\s*FROM\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
string AddSelectClause<T>(string sql) string AddSelectClause<T>(string sql)
{ {
if (sql.StartsWith(";")) if (sql.StartsWith(";"))
@ -734,9 +758,6 @@ namespace PetaPoco
// Return a typed list of pocos // Return a typed list of pocos
public List<T> Fetch<T>(string sql, params object[] args) public List<T> Fetch<T>(string sql, params object[] args)
{ {
if (EnableAutoSelect)
sql = AddSelectClause<T>(sql);
return Fetch<T>(new Sql(sql, args)); return Fetch<T>(new Sql(sql, args));
} }
@ -745,26 +766,15 @@ namespace PetaPoco
return Query<T>(sql).ToList(); return Query<T>(sql).ToList();
} }
public List<T> Fetch<T>(long page, long itemsPerPage, string sql, params object[] args)
{
string sqlCount, sqlPage;
BuildPageQueries<T>(page, itemsPerPage, sql, ref args, out sqlCount, out sqlPage);
return Fetch<T>(sqlPage, args);
}
public List<T> Fetch<T>(long page, long itemsPerPage, Sql sql)
{
return Fetch<T>(page, itemsPerPage, sql.SQL, sql.Arguments);
}
public List<T> Fetch<T>() public List<T> Fetch<T>()
{ {
return Fetch<T>(AddSelectClause<T>("")); return Fetch<T>("");
} }
static Regex rxColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); static Regex rxColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
static Regex rxOrderBy = new Regex(@"\bORDER\s+BY\s+(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled); static Regex rxOrderBy = new Regex(@"\bORDER\s+BY\s+(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
public static bool SplitSqlForPaging<T>(string sql, out string sqlCount, out string sqlSelectRemoved, out string sqlOrderBy) static Regex rxDistinct = new Regex(@"\ADISTINCT\s", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
public static bool SplitSqlForPaging(string sql, out string sqlCount, out string sqlSelectRemoved, out string sqlOrderBy)
{ {
sqlSelectRemoved = null; sqlSelectRemoved = null;
sqlCount = null; sqlCount = null;
@ -777,35 +787,34 @@ namespace PetaPoco
// Save column list and replace with COUNT(*) // Save column list and replace with COUNT(*)
Group g = m.Groups[1]; Group g = m.Groups[1];
sqlCount = sql.Substring(0, g.Index) + "COUNT(*) " + sql.Substring(g.Index + g.Length);
sqlSelectRemoved = sql.Substring(g.Index); sqlSelectRemoved = sql.Substring(g.Index);
// Look for an "ORDER BY <whatever>" clause or primarykey from pocodata if (rxDistinct.IsMatch(sqlSelectRemoved))
var data = PocoData.ForType(typeof(T)); sqlCount = sql.Substring(0, g.Index) + "COUNT(" + m.Groups[1].ToString().Trim() + ") " + sql.Substring(g.Index + g.Length);
else
sqlCount = sql.Substring(0, g.Index) + "COUNT(*) " + sql.Substring(g.Index + g.Length);
// Look for an "ORDER BY <whatever>" clause
m = rxOrderBy.Match(sqlCount); m = rxOrderBy.Match(sqlCount);
if (!m.Success if (m.Success)
&& (string.IsNullOrEmpty(data.TableInfo.PrimaryKey) ||
(!data.TableInfo.PrimaryKey.Split(',').All(x => data.Columns.Values.Any(y => y.ColumnName.Equals(x, StringComparison.OrdinalIgnoreCase))))))
{ {
return false;
}
g = m.Groups[0]; g = m.Groups[0];
sqlOrderBy = m.Success ? g.ToString() : "ORDER BY " + data.TableInfo.PrimaryKey; sqlOrderBy = g.ToString();
sqlCount = sqlCount.Substring(0, g.Index) + sqlCount.Substring(g.Index + g.Length); sqlCount = sqlCount.Substring(0, g.Index) + sqlCount.Substring(g.Index + g.Length);
}
return true; return true;
} }
private void BuildPageQueries<T>(long skip, long take, string sql, ref object[] args, out string sqlCount, out string sqlPage) public void BuildPageQueries<T>(long skip, long take, string sql, ref object[] args, out string sqlCount, out string sqlPage)
{ {
// Add auto select clause // Add auto select clause
sql = AddSelectClause<T>(sql); sql=AddSelectClause<T>(sql);
// Split the SQL into the bits we need // Split the SQL into the bits we need
string sqlSelectRemoved, sqlOrderBy; string sqlSelectRemoved, sqlOrderBy;
if (!SplitSqlForPaging<T>(sql, out sqlCount, out sqlSelectRemoved, out sqlOrderBy)) if (!SplitSqlForPaging(sql, out sqlCount, out sqlSelectRemoved, out sqlOrderBy))
throw new Exception("Unable to parse SQL statement for paged query"); throw new Exception("Unable to parse SQL statement for paged query");
if (_dbType == DBType.Oracle && sqlSelectRemoved.StartsWith("*")) if (_dbType == DBType.Oracle && sqlSelectRemoved.StartsWith("*"))
throw new Exception("Query must alias '*' when performing a paged query.\neg. select t.* from table t order by t.id"); throw new Exception("Query must alias '*' when performing a paged query.\neg. select t.* from table t order by t.id");
@ -813,11 +822,14 @@ namespace PetaPoco
// Build the SQL for the actual final result // Build the SQL for the actual final result
if (_dbType == DBType.SqlServer || _dbType == DBType.Oracle) if (_dbType == DBType.SqlServer || _dbType == DBType.Oracle)
{ {
var fromIndex = sqlSelectRemoved.IndexOf("from", StringComparison.OrdinalIgnoreCase);
sqlSelectRemoved = rxOrderBy.Replace(sqlSelectRemoved, ""); sqlSelectRemoved = rxOrderBy.Replace(sqlSelectRemoved, "");
sqlPage = string.Format("SELECT * FROM (SELECT {2}, ROW_NUMBER() OVER ({0}) peta_rn {1}) peta_paged WHERE peta_rn>@{3} AND peta_rn<=@{4}", if (rxDistinct.IsMatch(sqlSelectRemoved))
sqlOrderBy, sqlSelectRemoved.Substring(fromIndex), sqlSelectRemoved.Substring(0, fromIndex - 1), args.Length, args.Length + 1); {
args = args.Concat(new object[] { skip, skip + take }).ToArray(); sqlSelectRemoved = "peta_inner.* FROM (SELECT " + sqlSelectRemoved + ") peta_inner";
}
sqlPage = string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER ({0}) peta_rn, {1}) peta_paged WHERE peta_rn>@{2} AND peta_rn<=@{3}",
sqlOrderBy==null ? "ORDER BY (SELECT NULL)" : sqlOrderBy, sqlSelectRemoved, args.Length, args.Length + 1);
args = args.Concat(new object[] { skip, skip+take }).ToArray();
} }
else if (_dbType == DBType.SqlServerCE) else if (_dbType == DBType.SqlServerCE)
{ {
@ -836,11 +848,7 @@ namespace PetaPoco
public Page<T> Page<T>(long page, long itemsPerPage, string sql, params object[] args) public Page<T> Page<T>(long page, long itemsPerPage, string sql, params object[] args)
{ {
string sqlCount, sqlPage; string sqlCount, sqlPage;
BuildPageQueries<T>((page-1)*itemsPerPage, itemsPerPage, sql, ref args, out sqlCount, out sqlPage);
long skip = (page - 1) * itemsPerPage;
long take = itemsPerPage;
BuildPageQueries<T>(skip, take, sql, ref args, out sqlCount, out sqlPage);
// Save the one-time command time out and use it for both queries // Save the one-time command time out and use it for both queries
int saveTimeout = OneTimeCommandTimeout; int saveTimeout = OneTimeCommandTimeout;
@ -868,14 +876,21 @@ namespace PetaPoco
return Page<T>(page, itemsPerPage, sql.SQL, sql.Arguments); return Page<T>(page, itemsPerPage, sql.SQL, sql.Arguments);
} }
public List<T> Fetch<T>(long page, long itemsPerPage, string sql, params object[] args)
{
return SkipTake<T>((page - 1) * itemsPerPage, itemsPerPage, sql, args);
}
public List<T> Fetch<T>(long page, long itemsPerPage, Sql sql)
{
return SkipTake<T>((page - 1) * itemsPerPage, itemsPerPage, sql.SQL, sql.Arguments);
}
public List<T> SkipTake<T>(long skip, long take, string sql, params object[] args) public List<T> SkipTake<T>(long skip, long take, string sql, params object[] args)
{ {
string sqlCount, sqlPage; string sqlCount, sqlPage;
BuildPageQueries<T>(skip, take, sql, ref args, out sqlCount, out sqlPage); BuildPageQueries<T>(skip, take, sql, ref args, out sqlCount, out sqlPage);
return Fetch<T>(sqlPage, args);
var result = Fetch<T>(sqlPage, args);
return result;
} }
public List<T> SkipTake<T>(long skip, long take, Sql sql) public List<T> SkipTake<T>(long skip, long take, Sql sql)
@ -886,20 +901,21 @@ namespace PetaPoco
// Return an enumerable collection of pocos // Return an enumerable collection of pocos
public IEnumerable<T> Query<T>(string sql, params object[] args) public IEnumerable<T> Query<T>(string sql, params object[] args)
{ {
if (EnableAutoSelect)
sql = AddSelectClause<T>(sql);
return Query<T>(new Sql(sql, args)); return Query<T>(new Sql(sql, args));
} }
public IEnumerable<T> Query<T>(Sql sql) public IEnumerable<T> Query<T>(Sql Sql)
{
using (MiniProfiler.StepStatic("Peta Query SQL"))
{ {
var sql = Sql.SQL;
var args = Sql.Arguments;
if (EnableAutoSelect)
sql = AddSelectClause<T>(sql);
OpenSharedConnection(); OpenSharedConnection();
try try
{ {
using (var cmd = CreateCommand(_sharedConnection, sql)) using (var cmd = CreateCommand(_sharedConnection, sql, args))
{ {
IDataReader r; IDataReader r;
var pd = PocoData.ForType(typeof(T)); var pd = PocoData.ForType(typeof(T));
@ -916,9 +932,7 @@ namespace PetaPoco
using (r) using (r)
{ {
var factory = var factory = pd.GetFactory(cmd.CommandText, _sharedConnection.ConnectionString, ForceDateTimesToUtc, 0, r.FieldCount, r) as Func<IDataReader, T>;
pd.GetFactory(cmd.CommandText, _sharedConnection.ConnectionString, ForceDateTimesToUtc, 0, r.FieldCount, r)
as Func<IDataReader, T>;
while (true) while (true)
{ {
T poco; T poco;
@ -944,7 +958,6 @@ namespace PetaPoco
CloseSharedConnection(); CloseSharedConnection();
} }
} }
}
// Multi Fetch // Multi Fetch
public List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args) { return Query<T1, T2, TRet>(cb, sql, args).ToList(); } public List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args) { return Query<T1, T2, TRet>(cb, sql, args).ToList(); }
@ -953,8 +966,8 @@ namespace PetaPoco
// Multi Query // Multi Query
public IEnumerable<TRet> Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args) { return Query<TRet>(new Type[] { typeof(T1), typeof(T2) }, cb, sql, args); } public IEnumerable<TRet> Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args) { return Query<TRet>(new Type[] { typeof(T1), typeof(T2) }, cb, sql, args); }
public IEnumerable<TRet> Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args) { return Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3) }, cb, sql, args); } public IEnumerable<TRet> Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args) { return Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3)}, cb, sql, args); }
public IEnumerable<TRet> Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args) { return Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, cb, sql, args); } public IEnumerable<TRet> Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args) { return Query<TRet>(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4)}, cb, sql, args); }
// Multi Fetch (SQL builder) // Multi Fetch (SQL builder)
public List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql) { return Query<T1, T2, TRet>(cb, sql.SQL, sql.Arguments).ToList(); } public List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql) { return Query<T1, T2, TRet>(cb, sql.SQL, sql.Arguments).ToList(); }
@ -1108,7 +1121,7 @@ namespace PetaPoco
// Call each delegate // Call each delegate
var dels = new List<Delegate>(); var dels = new List<Delegate>();
int pos = 0; int pos = 0;
for (int i = 0; i < types.Length; i++) for (int i=0; i<types.Length; i++)
{ {
// Add to list of delegates to call // Add to list of delegates to call
var del = FindSplitPoint(types[i], i + 1 < types.Length ? types[i + 1] : null, sql, r, ref pos); var del = FindSplitPoint(types[i], i + 1 < types.Length ? types[i + 1] : null, sql, r, ref pos);
@ -1136,7 +1149,7 @@ namespace PetaPoco
// Various cached stuff // Various cached stuff
static Dictionary<string, object> MultiPocoFactories = new Dictionary<string, object>(); static Dictionary<string, object> MultiPocoFactories = new Dictionary<string, object>();
static Dictionary<string, object> AutoMappers = new Dictionary<string, object>(); static Dictionary<string, object> AutoMappers = new Dictionary<string, object>();
static ReaderWriterLockSlim RWLock = new ReaderWriterLockSlim(); static System.Threading.ReaderWriterLockSlim RWLock = new System.Threading.ReaderWriterLockSlim();
// Get (or create) the multi-poco factory for a query // Get (or create) the multi-poco factory for a query
Func<IDataReader, object, TRet> GetMultiPocoFactory<TRet>(Type[] types, string sql, IDataReader r) Func<IDataReader, object, TRet> GetMultiPocoFactory<TRet>(Type[] types, string sql, IDataReader r)
@ -1192,8 +1205,6 @@ namespace PetaPoco
// Actual implementation of the multi-poco query // Actual implementation of the multi-poco query
public IEnumerable<TRet> Query<TRet>(Type[] types, object cb, string sql, params object[] args) public IEnumerable<TRet> Query<TRet>(Type[] types, object cb, string sql, params object[] args)
{
using (MiniProfiler.StepStatic("Peta Query Type[]"))
{ {
OpenSharedConnection(); OpenSharedConnection();
try try
@ -1214,7 +1225,7 @@ namespace PetaPoco
var factory = GetMultiPocoFactory<TRet>(types, sql, r); var factory = GetMultiPocoFactory<TRet>(types, sql, r);
if (cb == null) if (cb == null)
cb = GetAutoMapper(types.ToArray()); cb = GetAutoMapper(types.ToArray());
bool bNeedTerminator = false; bool bNeedTerminator=false;
using (r) using (r)
{ {
while (true) while (true)
@ -1253,7 +1264,6 @@ namespace PetaPoco
CloseSharedConnection(); CloseSharedConnection();
} }
} }
}
public bool Exists<T>(object primaryKey) public bool Exists<T>(object primaryKey)
{ {
@ -1340,7 +1350,7 @@ namespace PetaPoco
public string EscapeTableName(string str) public string EscapeTableName(string str)
{ {
// Assume table names with "dot", or opening sq is already escaped // Assume table names with "dot" are already escaped
return str.IndexOf('.') >= 0 ? str : EscapeSqlIdentifier(str); return str.IndexOf('.') >= 0 ? str : EscapeSqlIdentifier(str);
} }
@ -1352,9 +1362,11 @@ namespace PetaPoco
return string.Format("`{0}`", str); return string.Format("`{0}`", str);
case DBType.PostgreSQL: case DBType.PostgreSQL:
case DBType.Oracle:
return string.Format("\"{0}\"", str); return string.Format("\"{0}\"", str);
case DBType.Oracle:
return string.Format("\"{0}\"", str.ToUpperInvariant());
default: default:
return string.Format("[{0}]", str); return string.Format("[{0}]", str);
} }
@ -1369,8 +1381,6 @@ namespace PetaPoco
// as the primary key the id of the new record is assigned to it. Either way, // as the primary key the id of the new record is assigned to it. Either way,
// the new id is returned. // the new id is returned.
public object Insert(string tableName, string primaryKeyName, bool autoIncrement, object poco) public object Insert(string tableName, string primaryKeyName, bool autoIncrement, object poco)
{
using (MiniProfiler.StepStatic("Peta Insert " + tableName))
{ {
try try
{ {
@ -1392,7 +1402,7 @@ namespace PetaPoco
continue; continue;
// Don't insert the primary key (except under oracle where we need bring in the next sequence value) // Don't insert the primary key (except under oracle where we need bring in the next sequence value)
if (autoIncrement && primaryKeyName != null && string.Compare(i.Key, primaryKeyName, true) == 0) if (autoIncrement && primaryKeyName != null && string.Compare(i.Key, primaryKeyName, true)==0)
{ {
if (_dbType == DBType.Oracle && !string.IsNullOrEmpty(pd.TableInfo.SequenceName)) if (_dbType == DBType.Oracle && !string.IsNullOrEmpty(pd.TableInfo.SequenceName))
{ {
@ -1421,15 +1431,17 @@ namespace PetaPoco
string.Join(",", values.ToArray()) string.Join(",", values.ToArray())
); );
object id;
if (!autoIncrement) if (!autoIncrement)
{ {
DoPreExecute(cmd); DoPreExecute(cmd);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
OnExecutedCommand(cmd); OnExecutedCommand(cmd);
return true; id = true;
} }
else
object id; {
switch (_dbType) switch (_dbType)
{ {
@ -1514,6 +1526,7 @@ namespace PetaPoco
pc.SetValue(poco, pc.ChangeType(id)); pc.SetValue(poco, pc.ChangeType(id));
} }
} }
}
// Assign the Version column // Assign the Version column
if (!string.IsNullOrEmpty(versionName)) if (!string.IsNullOrEmpty(versionName))
@ -1539,7 +1552,6 @@ namespace PetaPoco
throw; throw;
} }
} }
}
// Insert an annotated poco object // Insert an annotated poco object
public object Insert(object poco) public object Insert(object poco)
@ -1561,10 +1573,14 @@ namespace PetaPoco
} }
} }
// Update a record with values from a poco. primary key value can be either supplied or read from the poco
public int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue) public int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue)
{ {
using (MiniProfiler.StepStatic("Peta Update " + tableName)) return Update(tableName, primaryKeyName, poco, primaryKeyValue, null);
}
// Update a record with values from a poco. primary key value can be either supplied or read from the poco
public int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable<string> columns)
{ {
try try
{ {
@ -1575,7 +1591,7 @@ namespace PetaPoco
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
var index = 0; var index = 0;
var pd = PocoData.ForObject(poco, primaryKeyName); var pd = PocoData.ForObject(poco,primaryKeyName);
string versionName = null; string versionName = null;
object versionValue = null; object versionValue = null;
@ -1594,6 +1610,9 @@ namespace PetaPoco
if (i.Value.ResultColumn) if (i.Value.ResultColumn)
continue; continue;
if (!i.Value.VersionColumn && columns != null && !columns.Contains(i.Value.ColumnName, StringComparer.OrdinalIgnoreCase))
continue;
object value = i.Value.PropertyInfo.GetValue(poco, null); object value = i.Value.PropertyInfo.GetValue(poco, null);
if (i.Value.VersionColumn) if (i.Value.VersionColumn)
@ -1612,9 +1631,9 @@ namespace PetaPoco
AddParam(cmd, value, _paramPrefix); AddParam(cmd, value, _paramPrefix);
} }
cmd.CommandText = string.Format("UPDATE {0} SET {1} WHERE {2}", cmd.CommandText = string.Format("UPDATE {0} SET {1} WHERE {2}",
EscapeSqlIdentifier(tableName), sb.ToString(), EscapeTableName(tableName), sb.ToString(), BuildPrimaryKeySql(primaryKeyValuePairs, ref index));
BuildPrimaryKeySql(primaryKeyValuePairs, ref index));
foreach (var keyValue in primaryKeyValuePairs) foreach (var keyValue in primaryKeyValuePairs)
{ {
@ -1623,8 +1642,7 @@ namespace PetaPoco
if (!string.IsNullOrEmpty(versionName)) if (!string.IsNullOrEmpty(versionName))
{ {
cmd.CommandText += string.Format(" AND {0} = {1}{2}", EscapeSqlIdentifier(versionName), _paramPrefix, cmd.CommandText += string.Format(" AND {0} = {1}{2}", EscapeSqlIdentifier(versionName), _paramPrefix, index++);
index++);
AddParam(cmd, versionValue, _paramPrefix); AddParam(cmd, versionValue, _paramPrefix);
} }
@ -1635,14 +1653,11 @@ namespace PetaPoco
OnExecutedCommand(cmd); OnExecutedCommand(cmd);
// Set Version // Set Version
if (!string.IsNullOrEmpty(versionName)) if (!string.IsNullOrEmpty(versionName)) {
{
PocoColumn pc; PocoColumn pc;
if (pd.Columns.TryGetValue(versionName, out pc)) if (pd.Columns.TryGetValue(versionName, out pc))
{ {
pc.PropertyInfo.SetValue(poco, pc.PropertyInfo.SetValue(poco, Convert.ChangeType(Convert.ToInt64(versionValue)+1, pc.PropertyInfo.PropertyType), null);
Convert.ChangeType(Convert.ToInt64(versionValue) + 1,
pc.PropertyInfo.PropertyType), null);
} }
} }
@ -1660,7 +1675,6 @@ namespace PetaPoco
throw; throw;
} }
} }
}
private string BuildPrimaryKeySql(Dictionary<string, object> primaryKeyValuePair, ref int index) private string BuildPrimaryKeySql(Dictionary<string, object> primaryKeyValuePair, ref int index)
{ {
@ -1696,15 +1710,29 @@ namespace PetaPoco
return Update(tableName, primaryKeyName, poco, null); return Update(tableName, primaryKeyName, poco, null);
} }
public int Update(string tableName, string primaryKeyName, object poco, IEnumerable<string> columns)
{
return Update(tableName, primaryKeyName, poco, null, columns);
}
public int Update(object poco, IEnumerable<string> columns)
{
return Update(poco, null, columns);
}
public int Update(object poco) public int Update(object poco)
{ {
return Update(poco, null); return Update(poco, null, null);
} }
public int Update(object poco, object primaryKeyValue) public int Update(object poco, object primaryKeyValue)
{
return Update(poco, primaryKeyValue, null);
}
public int Update(object poco, object primaryKeyValue, IEnumerable<string> columns)
{ {
var pd = PocoData.ForType(poco.GetType()); var pd = PocoData.ForType(poco.GetType());
return Update(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, poco, primaryKeyValue); return Update(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, poco, primaryKeyValue, columns);
} }
public int Update<T>(string sql, params object[] args) public int Update<T>(string sql, params object[] args)
@ -1757,7 +1785,7 @@ namespace PetaPoco
// Do it // Do it
var index = 0; var index = 0;
var sql = string.Format("DELETE FROM {0} WHERE {1}", tableName, BuildPrimaryKeySql(primaryKeyValuePairs, ref index)); var sql = string.Format("DELETE FROM {0} WHERE {1}", tableName, BuildPrimaryKeySql(primaryKeyValuePairs, ref index));
return Execute(sql, primaryKeyValuePairs.Select(x => x.Value).ToArray()); return Execute(sql, primaryKeyValuePairs.Select(x=>x.Value).ToArray());
} }
public int Delete(object poco) public int Delete(object poco)
@ -1887,7 +1915,7 @@ namespace PetaPoco
cmd.CommandTimeout = OneTimeCommandTimeout; cmd.CommandTimeout = OneTimeCommandTimeout;
OneTimeCommandTimeout = 0; OneTimeCommandTimeout = 0;
} }
else if (CommandTimeout != 0) else if (CommandTimeout!=0)
{ {
cmd.CommandTimeout = CommandTimeout; cmd.CommandTimeout = CommandTimeout;
} }
@ -1947,18 +1975,18 @@ namespace PetaPoco
public virtual object GetValue(object target) { return PropertyInfo.GetValue(target, null); } public virtual object GetValue(object target) { return PropertyInfo.GetValue(target, null); }
public virtual object ChangeType(object val) { return Convert.ChangeType(val, PropertyInfo.PropertyType); } public virtual object ChangeType(object val) { return Convert.ChangeType(val, PropertyInfo.PropertyType); }
} }
internal class ExpandoColumn : PocoColumn public class ExpandoColumn : PocoColumn
{ {
public override void SetValue(object target, object val) { (target as IDictionary<string, object>)[ColumnName] = val; } public override void SetValue(object target, object val) { (target as IDictionary<string, object>)[ColumnName]=val; }
public override object GetValue(object target) public override object GetValue(object target)
{ {
object val = null; object val=null;
(target as IDictionary<string, object>).TryGetValue(ColumnName, out val); (target as IDictionary<string, object>).TryGetValue(ColumnName, out val);
return val; return val;
} }
public override object ChangeType(object val) { return val; } public override object ChangeType(object val) { return val; }
} }
internal class PocoData public class PocoData
{ {
public static PocoData ForObject(object o, string primaryKeyName) public static PocoData ForObject(object o, string primaryKeyName)
{ {
@ -1983,7 +2011,7 @@ namespace PetaPoco
#endif #endif
return ForType(t); return ForType(t);
} }
static ReaderWriterLockSlim RWLock = new ReaderWriterLockSlim(); static System.Threading.ReaderWriterLockSlim RWLock = new System.Threading.ReaderWriterLockSlim();
public static PocoData ForType(Type t) public static PocoData ForType(Type t)
{ {
#if !PETAPOCO_NO_DYNAMIC #if !PETAPOCO_NO_DYNAMIC
@ -2031,7 +2059,7 @@ namespace PetaPoco
public PocoData(Type t) public PocoData(Type t)
{ {
type = t; type = t;
TableInfo = new TableInfo(); TableInfo=new TableInfo();
// Get the table name // Get the table name
var a = t.GetCustomAttributes(typeof(TableNameAttribute), true); var a = t.GetCustomAttributes(typeof(TableNameAttribute), true);
@ -2047,8 +2075,8 @@ namespace PetaPoco
TableInfo.AutoIncrement = TableInfo.AutoIncrement ? !TableInfo.PrimaryKey.Contains(',') : TableInfo.AutoIncrement; TableInfo.AutoIncrement = TableInfo.AutoIncrement ? !TableInfo.PrimaryKey.Contains(',') : TableInfo.AutoIncrement;
// Call column mapper // Call column mapper
if (Mapper != null) if (Database.Mapper != null)
Mapper.GetTableInfo(t, TableInfo); Database.Mapper.GetTableInfo(t, TableInfo);
// Work out bound properties // Work out bound properties
bool ExplicitColumns = t.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Length > 0; bool ExplicitColumns = t.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Length > 0;
@ -2084,7 +2112,7 @@ namespace PetaPoco
if (pc.ColumnName == null) if (pc.ColumnName == null)
{ {
pc.ColumnName = pi.Name; pc.ColumnName = pi.Name;
if (Mapper != null && !Mapper.MapPropertyToColumn(pi, ref pc.ColumnName, ref pc.ResultColumn)) if (Database.Mapper != null && !Database.Mapper.MapPropertyToColumn(pi, ref pc.ColumnName, ref pc.ResultColumn))
continue; continue;
} }
@ -2236,8 +2264,10 @@ namespace PetaPoco
{ {
// Get the PocoColumn for this db column, ignore if not known // Get the PocoColumn for this db column, ignore if not known
PocoColumn pc; PocoColumn pc;
if (!Columns.TryGetValue(r.GetName(i), out pc)) if (!Columns.TryGetValue(r.GetName(i), out pc) && !Columns.TryGetValue(r.GetName(i).Replace("_", ""), out pc))
{
continue; continue;
}
// Get the source type for this column // Get the source type for this column
var srcType = r.GetFieldType(i); var srcType = r.GetFieldType(i);
@ -2301,6 +2331,13 @@ namespace PetaPoco
il.MarkLabel(lblNext); il.MarkLabel(lblNext);
} }
var fnOnLoaded = RecurseInheritedTypes<MethodInfo>(type, (x) => x.GetMethod("OnLoaded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null));
if (fnOnLoaded != null)
{
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Callvirt, fnOnLoaded);
}
} }
il.Emit(OpCodes.Ret); il.Emit(OpCodes.Ret);
@ -2336,12 +2373,20 @@ namespace PetaPoco
Func<object, object> converter = null; Func<object, object> converter = null;
// Get converter from the mapper // Get converter from the mapper
if (Mapper != null) if (Database.Mapper != null)
{
if (pc != null)
{
converter = Database.Mapper.GetFromDbConverter(pc.PropertyInfo, srcType);
}
else
{ {
DestinationInfo destinationInfo = pc != null var m2 = Database.Mapper as IMapper2;
? new DestinationInfo(pc.PropertyInfo) if (m2 != null)
: new DestinationInfo(dstType); {
converter = Mapper.GetFromDbConverter(destinationInfo, srcType); converter = m2.GetFromDbConverter(dstType, srcType);
}
}
} }
// Standard DateTime->Utc mapper // Standard DateTime->Utc mapper
@ -2369,6 +2414,19 @@ namespace PetaPoco
} }
static T RecurseInheritedTypes<T>(Type t, Func<Type, T> cb)
{
while (t != null)
{
T info = cb(t);
if (info != null)
return info;
t = t.BaseType;
}
return default(T);
}
static Dictionary<Type, PocoData> m_PocoDatas = new Dictionary<Type, PocoData>(); static Dictionary<Type, PocoData> m_PocoDatas = new Dictionary<Type, PocoData>();
static List<Func<object, object>> m_Converters = new List<Func<object, object>>(); static List<Func<object, object>> m_Converters = new List<Func<object, object>>();
static MethodInfo fnGetValue = typeof(IDataRecord).GetMethod("GetValue", new Type[] { typeof(int) }); static MethodInfo fnGetValue = typeof(IDataRecord).GetMethod("GetValue", new Type[] { typeof(int) });
@ -2411,7 +2469,7 @@ namespace PetaPoco
_db.BeginTransaction(); _db.BeginTransaction();
} }
public void Complete() public virtual void Complete()
{ {
_db.CompleteTransaction(); _db.CompleteTransaction();
_db = null; _db = null;

@ -14,9 +14,6 @@ namespace NzbDrone.Core.Providers
private const string TVDB_APIKEY = "5D2D188E86E07F4F"; private const string TVDB_APIKEY = "5D2D188E86E07F4F";
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly Regex CleanUpRegex = new Regex(@"((\s|^)the(\s|$))|((\s|^)and(\s|$))|[^a-z]",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
private readonly TvdbHandler _handler; private readonly TvdbHandler _handler;
public TvDbProvider() public TvDbProvider()
@ -48,6 +45,8 @@ namespace NzbDrone.Core.Providers
//Fix American Dad's scene gongshow //Fix American Dad's scene gongshow
if (result != null && result.Id == 73141) if (result != null && result.Id == 73141)
{ {
result.Episodes = result.Episodes.Where(e => e.SeasonNumber == 0 || e.EpisodeNumber > 0).ToList();
var seasonOneEpisodeCount = result.Episodes.Where(e => e.SeasonNumber == 1).Count(); var seasonOneEpisodeCount = result.Episodes.Where(e => e.SeasonNumber == 1).Count();
var seasonOneId = result.Episodes.Where(e => e.SeasonNumber == 1).First().SeasonId; var seasonOneId = result.Episodes.Where(e => e.SeasonNumber == 1).First().SeasonId;

Loading…
Cancel
Save