Merge branch 'master' of git://github.com/kayone/NzbDrone
|
@ -145,7 +145,7 @@
|
||||||
<virtualDirectory path="/" physicalPath="%NZBDRONE_PATH%\NZBDrone.Web" />
|
<virtualDirectory path="/" physicalPath="%NZBDRONE_PATH%\NZBDrone.Web" />
|
||||||
</application>
|
</application>
|
||||||
<bindings>
|
<bindings>
|
||||||
<binding protocol="http" bindingInformation="*:8980:" />
|
<binding protocol="http" bindingInformation="*:8989:" />
|
||||||
</bindings>
|
</bindings>
|
||||||
</site>
|
</site>
|
||||||
<applicationDefaults applicationPool="IISExpressAppPool" />
|
<applicationDefaults applicationPool="IISExpressAppPool" />
|
||||||
|
|
|
@ -60,16 +60,20 @@ namespace NzbDrone.Core.Test
|
||||||
public void newzbin_rss_fetch()
|
public void newzbin_rss_fetch()
|
||||||
{
|
{
|
||||||
var mocker = new AutoMoqer();
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.Resolve<HttpProvider>();
|
||||||
mocker.GetMock<HttpProvider>()
|
|
||||||
.Setup(h => h.DownloadStream(It.IsAny<String>(), It.IsAny<NetworkCredential>()))
|
|
||||||
.Returns(File.OpenRead(".\\Files\\Rss\\newzbin.xml"));
|
|
||||||
|
|
||||||
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
||||||
mocker.GetMock<IndexerProvider>()
|
mocker.GetMock<IndexerProvider>()
|
||||||
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
||||||
.Returns(fakeSettings);
|
.Returns(fakeSettings);
|
||||||
|
|
||||||
|
mocker.GetMock<ConfigProvider>()
|
||||||
|
.SetupGet(c => c.NewzbinUsername)
|
||||||
|
.Returns("nzbdrone");
|
||||||
|
|
||||||
|
mocker.GetMock<ConfigProvider>()
|
||||||
|
.SetupGet(c => c.NewzbinPassword)
|
||||||
|
.Returns("smartar39865");
|
||||||
|
|
||||||
var newzbinProvider = mocker.Resolve<Newzbin>();
|
var newzbinProvider = mocker.Resolve<Newzbin>();
|
||||||
var parseResults = newzbinProvider.FetchRss();
|
var parseResults = newzbinProvider.FetchRss();
|
||||||
|
|
||||||
|
@ -84,8 +88,7 @@ namespace NzbDrone.Core.Test
|
||||||
parseResults.Should().OnlyContain(s => s.Indexer == newzbinProvider.Name);
|
parseResults.Should().OnlyContain(s => s.Indexer == newzbinProvider.Name);
|
||||||
parseResults.Should().OnlyContain(s => !String.IsNullOrEmpty(s.NzbTitle));
|
parseResults.Should().OnlyContain(s => !String.IsNullOrEmpty(s.NzbTitle));
|
||||||
|
|
||||||
|
ExceptionVerification.IgnoreWarns();
|
||||||
ExceptionVerification.ExcpectedWarns(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -180,7 +183,7 @@ namespace NzbDrone.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("simpsons", 21, 23)]
|
[TestCase("simpsons", 21, 23)]
|
||||||
[TestCase("Hawaii Five-0", 1, 5)]
|
[TestCase("Hawaii Five-0 2010", 1, 5)]
|
||||||
public void newzbin_search_returns_valid_results(string title, int season, int episode)
|
public void newzbin_search_returns_valid_results(string title, int season, int episode)
|
||||||
{
|
{
|
||||||
var mocker = new AutoMoqer();
|
var mocker = new AutoMoqer();
|
||||||
|
@ -198,7 +201,7 @@ namespace NzbDrone.Core.Test
|
||||||
var result = mocker.Resolve<Newzbin>().FetchEpisode(title, season, episode);
|
var result = mocker.Resolve<Newzbin>().FetchEpisode(title, season, episode);
|
||||||
|
|
||||||
result.Should().NotBeEmpty();
|
result.Should().NotBeEmpty();
|
||||||
result.Should().OnlyContain(r => r.CleanTitle == title);
|
result.Should().OnlyContain(r => r.CleanTitle == Parser.NormalizeTitle(title));
|
||||||
result.Should().OnlyContain(r => r.SeasonNumber == season);
|
result.Should().OnlyContain(r => r.SeasonNumber == season);
|
||||||
result.Should().OnlyContain(r => r.EpisodeNumbers.Contains(episode));
|
result.Should().OnlyContain(r => r.EpisodeNumbers.Contains(episode));
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,26 +60,6 @@ namespace NzbDrone.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestCase("D:\\TV Shows\\")]
|
|
||||||
[TestCase("//server//folder")]
|
|
||||||
public void UpdateRootDir(string newPath)
|
|
||||||
{
|
|
||||||
//Setup
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var rootDirProvider = mocker.Resolve<RootDirProvider>();
|
|
||||||
rootDirProvider.Add(new RootDir { Path = @"C:\TV" });
|
|
||||||
rootDirProvider.Update(new RootDir { Id = 1, Path = newPath });
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
var rootDirs = rootDirProvider.GetAll();
|
|
||||||
rootDirs.Should().HaveCount(1);
|
|
||||||
newPath.Should().Be(rootDirs.First().Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void RemoveRootDir()
|
public void RemoveRootDir()
|
||||||
{
|
{
|
||||||
|
@ -152,14 +132,5 @@ namespace NzbDrone.Core.Test
|
||||||
mocker.Resolve<RootDirProvider>().Add(new RootDir { Id = 0, Path = path });
|
mocker.Resolve<RootDirProvider>().Add(new RootDir { Id = 0, Path = path });
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("")]
|
|
||||||
[TestCase(null)]
|
|
||||||
[TestCase("BAD PATH")]
|
|
||||||
[ExpectedException(typeof(ArgumentException))]
|
|
||||||
public void invalid_folder_path_throws_on_update(string path)
|
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
mocker.Resolve<RootDirProvider>().Update(new RootDir { Id = 2, Path = path });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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.Configuration;
|
|
||||||
using System.Data;
|
|
||||||
using System.Data.Common;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Text;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Data;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
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
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DestinationInfo
|
//public class DestinationInfo
|
||||||
{
|
//{
|
||||||
public DestinationInfo(Type type)
|
// public DestinationInfo(Type type)
|
||||||
{
|
// {
|
||||||
Type = type;
|
// Type = type;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public DestinationInfo(PropertyInfo propertyInfo)
|
// public DestinationInfo(PropertyInfo propertyInfo)
|
||||||
{
|
// {
|
||||||
PropertyInfo = propertyInfo;
|
// PropertyInfo = propertyInfo;
|
||||||
Type = propertyInfo.PropertyType;
|
// Type = propertyInfo.PropertyType;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public PropertyInfo PropertyInfo { get; private set; }
|
// public PropertyInfo PropertyInfo { get; private set; }
|
||||||
public Type Type { 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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
sb.Append((sb.Length == 0 ? "@" : ",@") + args_dest.Count.ToString());
|
var indexOfExistingValue = args_dest.IndexOf(i);
|
||||||
|
if (indexOfExistingValue >= 0)
|
||||||
|
{
|
||||||
|
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,9 +540,9 @@ 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,10 +822,13 @@ 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);
|
{
|
||||||
|
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();
|
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(); }
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -1947,7 +1975,7 @@ 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)
|
||||||
|
@ -1958,7 +1986,7 @@ namespace PetaPoco
|
||||||
}
|
}
|
||||||
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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
DestinationInfo destinationInfo = pc != null
|
if (pc != null)
|
||||||
? new DestinationInfo(pc.PropertyInfo)
|
{
|
||||||
: new DestinationInfo(dstType);
|
converter = Database.Mapper.GetFromDbConverter(pc.PropertyInfo, srcType);
|
||||||
converter = Mapper.GetFromDbConverter(destinationInfo, srcType);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var m2 = Database.Mapper as IMapper2;
|
||||||
|
if (m2 != null)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace NzbDrone.Core.Model.Notification
|
||||||
/// Gets or sets the title for this notification.
|
/// Gets or sets the title for this notification.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The title.</value>
|
/// <value>The title.</value>
|
||||||
public String Title { get; set; }
|
public String Title { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the current status of this task. this field could be use to show the currently processing item in a long running task.
|
/// Gets or sets the current status of this task. this field could be use to show the currently processing item in a long running task.
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace NzbDrone.Core.Providers
|
||||||
public class DiskScanProvider
|
public class DiskScanProvider
|
||||||
{
|
{
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
private static readonly string[] MediaExtentions = new[] { ".mkv", ".avi", ".wmv", ".mp4" };
|
private static readonly string[] MediaExtentions = new[] { ".mkv", ".avi", ".wmv", ".mp4", ".mpg", ".mpeg", ".xvid", ".flv", ".mov", ".vob", ".ts", ".rm", ".rmvb", ".xvid", ".dvr-ms" };
|
||||||
private readonly DiskProvider _diskProvider;
|
private readonly DiskProvider _diskProvider;
|
||||||
private readonly EpisodeProvider _episodeProvider;
|
private readonly EpisodeProvider _episodeProvider;
|
||||||
private readonly MediaFileProvider _mediaFileProvider;
|
private readonly MediaFileProvider _mediaFileProvider;
|
||||||
|
|
|
@ -16,13 +16,15 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const string UrlParams = "feed=rss&hauth=1&ps_rb_language=4096";
|
||||||
|
|
||||||
protected override string[] Urls
|
protected override string[] Urls
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
"http://www.newzbin.com/browse/category/p/tv?feed=rss&hauth=1"
|
"http://www.newzbin.com/browse/category/p/tv?" + UrlParams
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +40,7 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
protected override IList<string> GetSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber)
|
protected override IList<string> GetSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
|
|
||||||
return new List<string> { String.Format(@"http://www.newzbin.com/search/query/?q={0}+{1}x{2:00}&fpn=p&searchaction=Go&category=8&feed=rss&hauth=1", GetQueryTitle(seriesTitle), seasonNumber, episodeNumber) };
|
return new List<string> { String.Format(@"http://www.newzbin.com/search/query/?q={0}+{1}x{2:00}&fpn=p&searchaction=Go&category=8&{3}", GetQueryTitle(seriesTitle), seasonNumber, episodeNumber, UrlParams) };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
public override string Name
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
Logger.Error("Unable to find an episode {0} in database", targetId);
|
Logger.Error("Unable to find an episode {0} in database", targetId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
notification.CurrentMessage = "Searching for " + episode;
|
||||||
|
|
||||||
|
|
||||||
var series = episode.Series;
|
var series = episode.Series;
|
||||||
|
|
||||||
|
|
|
@ -20,33 +20,45 @@ namespace NzbDrone.Core.Providers
|
||||||
get { return new List<BasicNotification>(_basicNotifications.Values); }
|
get { return new List<BasicNotification>(_basicNotifications.Values); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual List<ProgressNotification> GetProgressNotifications
|
public virtual List<ProgressNotification> ProgressNotifications
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
lock (_lock)
|
||||||
var activeNotification = _progressNotification.Values.Where(p => p.Status == ProgressNotificationStatus.InProgress).ToList();
|
{
|
||||||
|
var activeNotification =
|
||||||
|
_progressNotification.Values.Where(p => p.Status == ProgressNotificationStatus.InProgress).
|
||||||
|
ToList();
|
||||||
|
|
||||||
if (activeNotification.Count == 0)
|
if (activeNotification.Count == 0)
|
||||||
{
|
{
|
||||||
//Get notifications that were recently done
|
//Get notifications that were recently done
|
||||||
activeNotification = _progressNotification.Values.Where(p => p.CompletedTime >= DateTime.Now.AddSeconds(-3)).OrderByDescending(c => c.CompletedTime).ToList();
|
activeNotification =
|
||||||
|
_progressNotification.Values.Where(p => p.CompletedTime >= DateTime.Now.AddSeconds(-3)).
|
||||||
|
OrderByDescending(c => c.CompletedTime).ToList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return activeNotification.ToList();
|
return activeNotification.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Register(ProgressNotification notification)
|
public virtual void Register(ProgressNotification notification)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
_progressNotification.Add(notification.Id, notification);
|
_progressNotification.Add(notification.Id, notification);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Register(BasicNotification notification)
|
public virtual void Register(BasicNotification notification)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
_basicNotifications.Add(notification.Id, notification);
|
_basicNotifications.Add(notification.Id, notification);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Dismiss(Guid notificationId)
|
public virtual void Dismiss(Guid notificationId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,13 +42,6 @@ namespace NzbDrone.Core.Providers
|
||||||
_database.Delete<RootDir>(rootDirId);
|
_database.Delete<RootDir>(rootDirId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Update(RootDir rootDir)
|
|
||||||
{
|
|
||||||
ValidatePath(rootDir);
|
|
||||||
|
|
||||||
_database.Update(rootDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ValidatePath(RootDir rootDir)
|
private static void ValidatePath(RootDir rootDir)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrWhiteSpace(rootDir.Path) || !Path.IsPathRooted(rootDir.Path))
|
if (String.IsNullOrWhiteSpace(rootDir.Path) || !Path.IsPathRooted(rootDir.Path))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 98 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 98 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 222 B |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 222 B |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 98 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 98 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 240 B |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 225 B |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 47 B |
Before Width: | Height: | Size: 47 B |
Before Width: | Height: | Size: 47 B |