|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Data.Common;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using NzbDrone.Common.Serializer;
|
|
|
|
|
using NzbDrone.Core.Datastore;
|
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Test.Framework
|
|
|
|
|
{
|
|
|
|
|
public interface IDirectDataMapper
|
|
|
|
|
{
|
|
|
|
|
List<Dictionary<string, object>> Query(string sql);
|
|
|
|
|
List<T> Query<T>(string sql) where T : new();
|
|
|
|
|
T QueryScalar<T>(string sql);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class DirectDataMapper : IDirectDataMapper
|
|
|
|
|
{
|
|
|
|
|
private readonly DbProviderFactory _providerFactory;
|
|
|
|
|
private readonly string _connectionString;
|
|
|
|
|
|
|
|
|
|
public DirectDataMapper(IDatabase database)
|
|
|
|
|
{
|
|
|
|
|
var dataMapper = database.GetDataMapper();
|
|
|
|
|
_providerFactory = dataMapper.ProviderFactory;
|
|
|
|
|
_connectionString = dataMapper.ConnectionString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private DbConnection OpenConnection()
|
|
|
|
|
{
|
|
|
|
|
var connection = _providerFactory.CreateConnection();
|
|
|
|
|
connection.ConnectionString = _connectionString;
|
|
|
|
|
connection.Open();
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DataTable GetDataTable(string sql)
|
|
|
|
|
{
|
|
|
|
|
using (var connection = OpenConnection())
|
|
|
|
|
{
|
|
|
|
|
using (var cmd = connection.CreateCommand())
|
|
|
|
|
{
|
|
|
|
|
var dataTable = new DataTable();
|
|
|
|
|
cmd.CommandText = sql;
|
|
|
|
|
dataTable.Load(cmd.ExecuteReader());
|
|
|
|
|
return dataTable;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<Dictionary<string, object>> Query(string sql)
|
|
|
|
|
{
|
|
|
|
|
var dataTable = GetDataTable(sql);
|
|
|
|
|
|
|
|
|
|
return dataTable.Rows.Cast<DataRow>().Select(MapToDictionary).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<T> Query<T>(string sql) where T : new()
|
|
|
|
|
{
|
|
|
|
|
var dataTable = GetDataTable(sql);
|
|
|
|
|
|
|
|
|
|
return dataTable.Rows.Cast<DataRow>().Select(MapToObject<T>).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public T QueryScalar<T>(string sql)
|
|
|
|
|
{
|
|
|
|
|
var dataTable = GetDataTable(sql);
|
|
|
|
|
|
|
|
|
|
return dataTable.Rows.Cast<DataRow>().Select(d => MapValue(d, 0, typeof(T))).Cast<T>().FirstOrDefault();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected Dictionary<string, object> MapToDictionary(DataRow dataRow)
|
|
|
|
|
{
|
|
|
|
|
var item = new Dictionary<string, object>();
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < dataRow.Table.Columns.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var columnName = dataRow.Table.Columns[i].ColumnName;
|
|
|
|
|
|
|
|
|
|
object value;
|
|
|
|
|
if (dataRow.ItemArray[i] == DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
value = null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
value = dataRow.ItemArray[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item[columnName] = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected T MapToObject<T>(DataRow dataRow) where T : new()
|
|
|
|
|
{
|
|
|
|
|
var item = new T();
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < dataRow.Table.Columns.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var columnName = dataRow.Table.Columns[i].ColumnName;
|
|
|
|
|
var propertyInfo = typeof(T).GetProperty(columnName);
|
|
|
|
|
|
|
|
|
|
if (propertyInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(string.Format("Column {0} doesn't exist on type {1}.", columnName, typeof(T)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var propertyType = propertyInfo.PropertyType;
|
|
|
|
|
|
|
|
|
|
if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
|
|
|
|
|
{
|
|
|
|
|
propertyType = propertyType.GetGenericArguments()[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object value = MapValue(dataRow, i, propertyType);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
propertyInfo.SetValue(item, value, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private object MapValue(DataRow dataRow, int i, Type targetType)
|
|
|
|
|
{
|
|
|
|
|
if (dataRow.ItemArray[i] == DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else if (dataRow.Table.Columns[i].DataType == typeof(string) && targetType != typeof(string))
|
|
|
|
|
{
|
|
|
|
|
return Json.Deserialize((string)dataRow.ItemArray[i], targetType);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Convert.ChangeType(dataRow.ItemArray[i], targetType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|