using System; using System.Collections.Generic; using System.Data; using Dapper; namespace NzbDrone.Core.Datastore { public static class SqlMapperExtensions { public static IEnumerable Query(this IDatabase db, string sql, object param = null) { using (var conn = db.OpenConnection()) { var items = SqlMapper.Query(conn, sql, param); if (TableMapping.Mapper.LazyLoadList.TryGetValue(typeof(T), out var lazyProperties)) { foreach (var item in items) { ApplyLazyLoad(db, item, lazyProperties); } } return items; } } public static IEnumerable Query(this IDatabase db, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { TReturn mapWithLazy(TFirst first, TSecond second) { ApplyLazyLoad(db, first); ApplyLazyLoad(db, second); return map(first, second); } IEnumerable result = null; using (var conn = db.OpenConnection()) { result = SqlMapper.Query(conn, sql, mapWithLazy, param, transaction, buffered, splitOn, commandTimeout, commandType); } return result; } public static IEnumerable Query(this IDatabase db, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { TReturn mapWithLazy(TFirst first, TSecond second, TThird third) { ApplyLazyLoad(db, first); ApplyLazyLoad(db, second); ApplyLazyLoad(db, third); return map(first, second, third); } IEnumerable result = null; using (var conn = db.OpenConnection()) { result = SqlMapper.Query(conn, sql, mapWithLazy, param, transaction, buffered, splitOn, commandTimeout, commandType); } return result; } public static IEnumerable Query(this IDatabase db, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { TReturn mapWithLazy(TFirst first, TSecond second, TThird third, TFourth fourth) { ApplyLazyLoad(db, first); ApplyLazyLoad(db, second); ApplyLazyLoad(db, third); ApplyLazyLoad(db, fourth); return map(first, second, third, fourth); } IEnumerable result = null; using (var conn = db.OpenConnection()) { result = SqlMapper.Query(conn, sql, mapWithLazy, param, transaction, buffered, splitOn, commandTimeout, commandType); } return result; } public static IEnumerable Query(this IDatabase db, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { TReturn mapWithLazy(TFirst first, TSecond second, TThird third, TFourth fourth, TFifth fifth) { ApplyLazyLoad(db, first); ApplyLazyLoad(db, second); ApplyLazyLoad(db, third); ApplyLazyLoad(db, fourth); ApplyLazyLoad(db, fifth); return map(first, second, third, fourth, fifth); } IEnumerable result = null; using (var conn = db.OpenConnection()) { result = SqlMapper.Query(conn, sql, mapWithLazy, param, transaction, buffered, splitOn, commandTimeout, commandType); } return result; } public static IEnumerable Query(this IDatabase db, SqlBuilder builder) { var type = typeof(T); var sql = builder.Select(type).AddSelectTemplate(type); return db.Query(sql.RawSql, sql.Parameters); } public static IEnumerable QueryJoined(this IDatabase db, SqlBuilder builder, Func mapper) { var type = typeof(T); var sql = builder.Select(type, typeof(T2)).AddSelectTemplate(type); return db.Query(sql.RawSql, mapper, sql.Parameters); } public static IEnumerable QueryJoined(this IDatabase db, SqlBuilder builder, Func mapper) { var type = typeof(T); var sql = builder.Select(type, typeof(T2), typeof(T3)).AddSelectTemplate(type); return db.Query(sql.RawSql, mapper, sql.Parameters); } public static IEnumerable QueryJoined(this IDatabase db, SqlBuilder builder, Func mapper) { var type = typeof(T); var sql = builder.Select(type, typeof(T2), typeof(T3), typeof(T4)).AddSelectTemplate(type); return db.Query(sql.RawSql, mapper, sql.Parameters); } public static IEnumerable QueryJoined(this IDatabase db, SqlBuilder builder, Func mapper) { var type = typeof(T); var sql = builder.Select(type, typeof(T2), typeof(T3), typeof(T4), typeof(T5)).AddSelectTemplate(type); return db.Query(sql.RawSql, mapper, sql.Parameters); } private static void ApplyLazyLoad(IDatabase db, TModel model) { if (TableMapping.Mapper.LazyLoadList.TryGetValue(typeof(TModel), out var lazyProperties)) { ApplyLazyLoad(db, model, lazyProperties); } } private static void ApplyLazyLoad(IDatabase db, TModel model, List lazyProperties) { if (model == null) { return; } foreach (var lazyProperty in lazyProperties) { var lazy = (ILazyLoaded)lazyProperty.LazyLoad.Clone(); lazy.Prepare(db, model); lazyProperty.Property.SetValue(model, lazy); } } } }