Support lateral queries on dapper

This commit is contained in:
Zoe Roux 2023-11-21 01:14:52 +01:00
parent ba83edd26c
commit 0ff03fb413
4 changed files with 52 additions and 9 deletions

View File

@ -170,7 +170,27 @@ namespace Kyoo.Abstractions.Models
/// The previous episode that should be seen before viewing this one.
/// </summary>
[Projectable(UseMemberBody = nameof(_PreviousEpisode), OnlyOnInclude = true)]
[LoadableRelation] public Episode? PreviousEpisode { get; set; }
[LoadableRelation(
// language=PostgreSQL
Sql = """
select
"pe".*,
from
episodes as "pe"
where
"pe".show_id = "this".show_id
and ("pe".absolute_number < "this".absolute_number
or "pe".season_number < "this".season_number
or ("pe".season_number = "this".season_number
and e.episode_number < "this".episode_number))
order by
"pe".absolute_number desc,
"pe".season_number desc,
"pe".episode_number desc
limit 1
"""
)]
public Episode? PreviousEpisode { get; set; }
private Episode? _PreviousEpisode => Show!.Episodes!
.OrderByDescending(x => x.AbsoluteNumber)
@ -186,7 +206,27 @@ namespace Kyoo.Abstractions.Models
/// The next episode to watch after this one.
/// </summary>
[Projectable(UseMemberBody = nameof(_NextEpisode), OnlyOnInclude = true)]
[LoadableRelation] public Episode? NextEpisode { get; set; }
[LoadableRelation(
// language=PostgreSQL
Sql = """
select
"ne".*,
from
episodes as "ne"
where
"ne".show_id = "this".show_id
and ("ne".absolute_number > "this".absolute_number
or "ne".season_number > "this".season_number
or ("ne".season_number = "this".season_number
and e.episode_number > "this".episode_number))
order by
"ne".absolute_number,
"ne".season_number,
"ne".episode_number
limit 1
"""
)]
public Episode? NextEpisode { get; set; }
private Episode? _NextEpisode => Show!.Episodes!
.OrderBy(x => x.AbsoluteNumber)

View File

@ -156,17 +156,17 @@ namespace Kyoo.Abstractions.Models
// language=PostgreSQL
Sql = """
select
fe.*
"fe".*
from (
select
e.*,
row_number() over (partition by e.show_id order by e.absolute_number, e.season_number, e.episode_number) as number
from
episodes as e) as fe
episodes as e) as "fe"
where
fe.number <= 1
"fe".number <= 1
""",
On = "show_id"
On = "show_id = \"this\".id"
)]
public Episode? FirstEpisode { get; set; }

View File

@ -77,7 +77,7 @@ public class Include<T>
// prop.PropertyType.GetElementType() ?? prop.PropertyType.GenericTypeArguments.First()
// );
// }
if (attr.Sql != null && attr.On != null)
if (attr.Sql != null)
return new CustomRelation(prop.Name, prop.PropertyType, attr.Sql, attr.On, prop.DeclaringType!);
throw new NotImplementedException();
})
@ -90,5 +90,5 @@ public class Include<T>
public record SingleRelation(string Name, Type type, string RelationIdName) : Metadata(Name);
public record CustomRelation(string Name, Type type, string Sql, string On, Type Declaring) : Metadata(Name);
public record CustomRelation(string Name, Type type, string Sql, string? On, Type Declaring) : Metadata(Name);
}

View File

@ -147,8 +147,11 @@ namespace Kyoo.Core.Controllers
break;
case Include<T>.CustomRelation(var name, var type, var sql, var on, var declaring):
string owner = config.First(x => x.Value == declaring).Key;
string lateral = sql.Contains("\"this\"") ? " lateral" : string.Empty;
sql = sql.Replace("\"this\"", owner);
on = on?.Replace("\"this\"", owner);
retConfig.Add($"r{relation}", type);
join.AppendLine($"left join ({sql}) as r{relation} on r{relation}.{on} = {owner}.id");
join.AppendLine($"left join{lateral} ({sql}) as r{relation} on r{relation}.{on}");
break;
default:
throw new NotImplementedException();