2021-08-27 11:03:47 -04:00
#nullable enable
2020-06-13 21:49:31 +02:00
using System.Text ;
using Dapper ;
2021-11-26 21:10:56 -05:00
namespace PluralKit.Core ;
public static class DatabaseViewsExt
2020-06-13 21:49:31 +02:00
{
2022-01-14 22:30:02 -05:00
public static Task < IEnumerable < ListedGroup > > QueryGroupList ( this IPKConnection conn , SystemId system ,
ListQueryOptions opts )
{
2024-10-01 08:56:38 -04:00
StringBuilder query ;
if ( opts . MemberFilter = = null )
query = new StringBuilder ( "select * from group_list where system = @system" ) ;
else
query = new StringBuilder ( "select group_list.* from group_members inner join group_list on group_list.id = group_members.group_id where member_id = @MemberFilter" ) ;
2022-01-14 22:30:02 -05:00
if ( opts . PrivacyFilter ! = null )
query . Append ( $" and visibility = {(int)opts.PrivacyFilter}" ) ;
if ( opts . Search ! = null )
{
static string Filter ( string column ) = >
$"(position(lower(@filter) in lower(coalesce({column}, ''))) > 0)" ;
2021-11-26 21:10:56 -05:00
2022-01-14 22:30:02 -05:00
query . Append ( $" and ({Filter(" name ")} or {Filter(" display_name ")}" ) ;
if ( opts . SearchDescription )
{
// We need to account for the possibility of description privacy when searching
// If we're looking up from the outside, only search "public_description" (defined in the view; null if desc is private)
// If we're the owner, just search the full description
var descriptionColumn =
opts . Context = = LookupContext . ByOwner ? "description" : "public_description" ;
query . Append ( $"or {Filter(descriptionColumn)}" ) ;
}
query . Append ( ")" ) ;
}
return conn . QueryAsync < ListedGroup > (
query . ToString ( ) ,
2024-10-01 08:56:38 -04:00
new { system , filter = opts . Search , memberFilter = opts . MemberFilter } ) ;
2022-01-14 22:30:02 -05:00
}
2021-11-26 21:10:56 -05:00
public static Task < IEnumerable < ListedMember > > QueryMemberList ( this IPKConnection conn , SystemId system ,
2022-01-14 22:30:02 -05:00
ListQueryOptions opts )
2020-06-13 21:49:31 +02:00
{
2021-11-26 21:10:56 -05:00
StringBuilder query ;
if ( opts . GroupFilter = = null )
query = new StringBuilder ( "select * from member_list where system = @system" ) ;
else
query = new StringBuilder (
"select member_list.* from group_members inner join member_list on member_list.id = group_members.member_id where group_id = @groupFilter" ) ;
2020-08-21 17:08:49 +02:00
2021-11-26 21:10:56 -05:00
if ( opts . PrivacyFilter ! = null )
query . Append ( $" and member_visibility = {(int)opts.PrivacyFilter}" ) ;
2021-08-27 11:03:47 -04:00
2021-11-26 21:10:56 -05:00
if ( opts . Search ! = null )
2020-06-13 21:49:31 +02:00
{
2021-11-26 21:10:56 -05:00
static string Filter ( string column ) = >
$"(position(lower(@filter) in lower(coalesce({column}, ''))) > 0)" ;
2020-06-13 21:49:31 +02:00
2021-11-26 21:10:56 -05:00
query . Append ( $" and ({Filter(" name ")} or {Filter(" display_name ")}" ) ;
if ( opts . SearchDescription )
2020-06-13 21:49:31 +02:00
{
2021-11-26 21:10:56 -05:00
// We need to account for the possibility of description privacy when searching
// If we're looking up from the outside, only search "public_description" (defined in the view; null if desc is private)
// If we're the owner, just search the full description
var descriptionColumn =
opts . Context = = LookupContext . ByOwner ? "description" : "public_description" ;
query . Append ( $"or {Filter(descriptionColumn)}" ) ;
2020-06-13 21:49:31 +02:00
}
2021-08-27 11:03:47 -04:00
2021-11-26 21:10:56 -05:00
query . Append ( ")" ) ;
2020-07-07 20:57:22 +02:00
}
2021-08-27 11:03:47 -04:00
2021-11-26 21:10:56 -05:00
return conn . QueryAsync < ListedMember > ( query . ToString ( ) ,
new { system , filter = opts . Search , groupFilter = opts . GroupFilter } ) ;
}
2022-01-14 22:30:02 -05:00
public struct ListQueryOptions
2021-11-26 21:10:56 -05:00
{
public PrivacyLevel ? PrivacyFilter ;
public string? Search ;
public bool SearchDescription ;
public LookupContext Context ;
public GroupId ? GroupFilter ;
2024-10-01 08:56:38 -04:00
public MemberId ? MemberFilter ;
2020-06-13 21:49:31 +02:00
}
}