diff --git a/src/Marr.Data/Parameters/ParameterChainMethods.cs b/src/Marr.Data/Parameters/ParameterChainMethods.cs
index c1ceef248..e00535ff7 100644
--- a/src/Marr.Data/Parameters/ParameterChainMethods.cs
+++ b/src/Marr.Data/Parameters/ParameterChainMethods.cs
@@ -14,8 +14,10 @@ You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see . */
using System;
+using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Runtime.InteropServices.ComTypes;
using Marr.Data.Converters;
namespace Marr.Data.Parameters
@@ -42,15 +44,25 @@ namespace Marr.Data.Parameters
Type valueType = value.GetType();
// Check for a registered IConverter
- IConverter converter = MapRepository.Instance.GetConverter(valueType);
- if (converter != null)
+ //If we have a list of ints, we ignore the converter since we want to do an in statement!
+ var list = value as List;
+ if (list != null)
{
- Parameter.Value = converter.ToDB(value);
+ Parameter.Value = $"{string.Join(",", list)}";
}
else
{
- Parameter.Value = value;
- }
+ IConverter converter = MapRepository.Instance.GetConverter(valueType);
+ if (converter != null)
+ {
+ Parameter.Value = converter.ToDB(value);
+ }
+ else
+ {
+ Parameter.Value = value;
+ }
+ }
+
//// Determine the correct DbType based on the passed in value type
//IDbTypeBuilder typeBuilder = MapRepository.Instance.DbTypeBuilder;
diff --git a/src/Marr.Data/QGen/Dialects/Dialect.cs b/src/Marr.Data/QGen/Dialects/Dialect.cs
index 195cabc1f..915866dfe 100644
--- a/src/Marr.Data/QGen/Dialects/Dialect.cs
+++ b/src/Marr.Data/QGen/Dialects/Dialect.cs
@@ -68,5 +68,13 @@ namespace Marr.Data.QGen.Dialects
{
get { return "({0} LIKE '%' + {1} + '%')"; }
}
+
+ public virtual string InFormat
+ {
+ get
+ {
+ return "({0} in ({1}))";
+ }
+ }
}
}
diff --git a/src/Marr.Data/QGen/WhereBuilder.cs b/src/Marr.Data/QGen/WhereBuilder.cs
index 64992d542..0a7c217f7 100644
--- a/src/Marr.Data/QGen/WhereBuilder.cs
+++ b/src/Marr.Data/QGen/WhereBuilder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Text;
using System.Linq.Expressions;
using System.Data.Common;
@@ -92,6 +93,10 @@ namespace Marr.Data.QGen
case "EndsWith":
Write_EndsWith(expression);
break;
+
+ case "In":
+ Write_In(expression);
+ break;
default:
string msg = string.Format("'{0}' expressions are not yet implemented in the where clause expression tree parser.", method);
@@ -140,31 +145,47 @@ namespace Marr.Data.QGen
return expression;
}
- private object GetRightValue(Expression rightExpression)
+ private object GetRightValue(Expression expression)
{
object rightValue = null;
-
- var right = rightExpression as ConstantExpression;
- if (right == null) // Value is not directly passed in as a constant
+
+ var simpleConstExp = expression as ConstantExpression;
+ if (simpleConstExp == null) // Value is not directly passed in as a constant
{
- var rightMemberExp = (rightExpression as MemberExpression);
- var parentMemberExpression = rightMemberExp.Expression as MemberExpression;
- if (parentMemberExpression != null) // Value is passed in as a property on a parent entity
+ MemberExpression memberExp = expression as MemberExpression;
+ ConstantExpression constExp = null;
+
+ // Value may be nested in multiple levels of objects/properties, so traverse the MemberExpressions
+ // until a ConstantExpression property value is found, and then unwind the stack to get the value.
+ var memberNames = new Stack();
+
+ while (memberExp != null)
{
- string entityName = (rightMemberExp.Expression as MemberExpression).Member.Name;
- var container = ((rightMemberExp.Expression as MemberExpression).Expression as ConstantExpression).Value;
- var entity = _repos.ReflectionStrategy.GetFieldValue(container, entityName);
- rightValue = _repos.ReflectionStrategy.GetFieldValue(entity, rightMemberExp.Member.Name);
+ memberNames.Push(memberExp.Member.Name);
+
+ // Function calls are not supported - user needs to simplify their Where expression.
+ var methodExp = memberExp.Expression as MethodCallExpression;
+ if (methodExp != null)
+ {
+ var errMsg = string.Format("Function calls are not supported by the Where clause expression parser. Please evaluate your function call, '{0}', manually and then use the resulting paremeter value in your Where expression.", methodExp.Method.Name);
+ throw new NotSupportedException(errMsg);
+ }
+
+ constExp = memberExp.Expression as ConstantExpression;
+ memberExp = memberExp.Expression as MemberExpression;
}
- else // Value is passed in as a variable
+
+ object entity = constExp.Value;
+ while (memberNames.Count > 0)
{
- var parent = (rightMemberExp.Expression as ConstantExpression).Value;
- rightValue = _repos.ReflectionStrategy.GetFieldValue(parent, rightMemberExp.Member.Name);
+ string entityName = memberNames.Pop();
+ entity = _repos.ReflectionStrategy.GetFieldValue(entity, entityName);
}
+ rightValue = entity;
}
else // Value is passed in directly as a constant
{
- rightValue = right.Value;
+ rightValue = simpleConstExp.Value;
}
return rightValue;
@@ -238,6 +259,17 @@ namespace Marr.Data.QGen
_sb.AppendFormat(_dialect.ContainsFormat, fqColumn, paramName);
}
+ private void Write_In(MethodCallExpression body)
+ {
+ object value = GetRightValue(body.Arguments[1]);
+ //string paramName = string.Concat(_paramPrefix, "P", _command.Parameters.Count.ToString());
+ //var parameter = new ParameterChainMethods(_command, paramName, value).Parameter;
+
+ MemberExpression memberExp = (body.Arguments[0] as MemberExpression);
+ string fqColumn = GetFullyQualifiedColumnName(memberExp.Member, memberExp.Expression.Type);
+ _sb.AppendFormat(_dialect.InFormat, fqColumn, string.Join(",", value as List));
+ }
+
private void Write_StartsWith(MethodCallExpression body)
{
// Add parameter to Command.Parameters
diff --git a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs
index b6fca0ea2..7a7efd12c 100644
--- a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs
+++ b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs
@@ -105,5 +105,9 @@ namespace NzbDrone.Common.Extensions
yield return buffer.Dequeue();
}
}
+ public static bool In(this T source, List list)
+ {
+ return list.Contains(source);
+ }
}
}
\ No newline at end of file
diff --git a/src/NzbDrone.Core/Datastore/BasicRepository.cs b/src/NzbDrone.Core/Datastore/BasicRepository.cs
index 88a78536e..7c3ff7642 100644
--- a/src/NzbDrone.Core/Datastore/BasicRepository.cs
+++ b/src/NzbDrone.Core/Datastore/BasicRepository.cs
@@ -83,11 +83,12 @@ namespace NzbDrone.Core.Datastore
{
var idList = ids.ToList();
var query = string.Format("Id IN ({0})", string.Join(",", idList));
- var result = Query.Where(query).ToList();
+ var result = Query.Where(m => m.Id.In(idList)).ToList();
+ //var result = Query.Where(query).ToList();
if (result.Count != idList.Count())
{
- throw new ApplicationException("Expected query to return {0} rows but returned {1}".Inject(idList.Count(), result.Count));
+ throw new ApplicationException("Expected query to return {0} rows but returned {1}.".Inject(idList.Count(), result.Count));
}
return result;
diff --git a/src/NzbDrone.Core/MediaFiles/RenameMovieFileService.cs b/src/NzbDrone.Core/MediaFiles/RenameMovieFileService.cs
index a1a24a626..626c8929f 100644
--- a/src/NzbDrone.Core/MediaFiles/RenameMovieFileService.cs
+++ b/src/NzbDrone.Core/MediaFiles/RenameMovieFileService.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.IO;
@@ -198,14 +199,22 @@ namespace NzbDrone.Core.MediaFiles
public void Execute(RenameMovieFolderCommand message)
{
- _logger.Debug("Renaming movie folder for selected movie if necessary");
- var moviesToRename = _movieService.GetMovies(message.MovieIds);
- foreach(var movie in moviesToRename)
- {
- var movieFiles = _mediaFileService.GetFilesByMovie(movie.Id);
- _logger.ProgressInfo("Renaming movie folder for {0}", movie.Title);
- RenameMoviePath(movie);
- }
+ try
+ {
+ _logger.Debug("Renaming movie folder for selected movie if necessary");
+ var moviesToRename = _movieService.GetMovies(message.MovieIds);
+ foreach(var movie in moviesToRename)
+ {
+ var movieFiles = _mediaFileService.GetFilesByMovie(movie.Id);
+ _logger.ProgressInfo("Renaming movie folder for {0}", movie.Title);
+ RenameMoviePath(movie);
+ }
+ }
+ catch (SQLiteException ex)
+ {
+ _logger.Warn(ex, "wtf: {0}, {1}", ex.ResultCode, ex.Data);
+ }
+
}
}
}