Class CharacterFriendService
Service for managing character friend relationships in the database. Provides async operations for CRUD operations on character friend data. Implements execution strategies for automatic retry on transient database failures. Returns DatabaseResult for consistent, safe error handling.
public sealed class CharacterFriendService : BaseService<CharacterFriendEntity>, ICharacterFriendService, ICountByKeyAction<long>, IDeleteByKeyVersionedAction<long>, IFetchCollectionByKeyAction<long, CharacterFriendData>
- Inheritance
-
CharacterFriendService
- Implements
- Inherited Members
Remarks
This service manages character friend relationships including:
- Friend relationship creation with atomic INSERT operations
- Friend deletion (individual and bulk)
- Friend retrieval and count queries
All exceptions are classified by BaseService and mapped to DatabaseResult error codes
(e.g., UNIQUE_VIOLATION, FOREIGN_KEY_VIOLATION, STALE_STATE, DATABASE_ERROR). Transient failures are retried automatically.
Methods return DatabaseResult to provide structured error handling
without throwing exceptions to calling code.
Constructors
CharacterFriendService(INpgsqlDbContextFactory)
Initializes a new instance of the CharacterFriendService class.
public CharacterFriendService(INpgsqlDbContextFactory dbContextFactory)
Parameters
dbContextFactoryINpgsqlDbContextFactoryFactory for creating database contexts.
Exceptions
- ArgumentNullException
Thrown when dbContextFactory is null.
Methods
CountAsync(long, CancellationToken)
Counts items for the given key.
public Task<DatabaseResult<int>> CountAsync(long characterId, CancellationToken cancellationToken = default)
Parameters
characterIdlongcancellationTokenCancellationTokenToken to cancel the operation.
Returns
DeleteAsync(long, long, long, CancellationToken)
Deletes a friend relationship for the specified character if incomingVersion is newer.
public Task<DatabaseResult> DeleteAsync(long characterId, long friendCharacterId, long incomingVersion, CancellationToken cancellationToken = default)
Parameters
characterIdlongThe owning character ID.
friendCharacterIdlongThe friend character ID.
incomingVersionlongThe authoritative, monotonic version for this delete operation.
cancellationTokenCancellationTokenToken to cancel the operation.
Returns
- Task<DatabaseResult>
A DatabaseResult indicating success or failure.
DeleteAsync(long, long, CancellationToken)
Deletes the entity identified by the given key if incomingVersion is newer.
public Task<DatabaseResult> DeleteAsync(long characterId, long incomingVersion, CancellationToken cancellationToken = default)
Parameters
characterIdlongincomingVersionlongThe authoritative, monotonic version for this delete operation.
cancellationTokenCancellationTokenToken to cancel the operation.
Returns
FetchAsync(long, CancellationToken)
Fetches a collection of items for the given key.
public Task<DatabaseResult<IReadOnlyList<CharacterFriendData>>> FetchAsync(long characterId, CancellationToken cancellationToken = default)
Parameters
characterIdlongcancellationTokenCancellationTokenToken to cancel the operation.
Returns
IsBlockedAsync(long, long, CancellationToken)
Determines whether characterId has blocked
otherCharacterId.
public Task<DatabaseResult<bool>> IsBlockedAsync(long characterId, long otherCharacterId, CancellationToken cancellationToken = default)
Parameters
characterIdlongThe character who may own a block entry.
otherCharacterIdlongThe character who may be blocked.
cancellationTokenCancellationTokenToken to cancel the operation.
Returns
- Task<DatabaseResult<bool>>
A DatabaseResult<T> that is true when an active row exists marking
otherCharacterIdas blocked bycharacterId.
Remarks
The is_blocked column has existed since the friend table was introduced and
nothing has ever read it — every block a player recorded was written and then ignored,
so blocking someone did not stop them inviting or whispering. This is the read side.
The check is deliberately one-directional: it answers "has A blocked B", so the caller
must ask it about the TARGET of an unwanted action, not about the initiator.
PersistAsync(long, long, long, bool, CancellationToken)
Persists a friend or block relationship for the specified character.
public Task<DatabaseResult> PersistAsync(long characterId, long friendCharacterId, long incomingVersion, bool isBlocked, CancellationToken cancellationToken = default)
Parameters
characterIdlongThe owning character ID.
friendCharacterIdlongThe friend character ID.
incomingVersionlongThe authoritative, monotonic version for this persist operation.
isBlockedboolWhen true the relationship is a block; when false it is a friend.
cancellationTokenCancellationTokenToken to cancel the operation.
Returns
- Task<DatabaseResult>
A DatabaseResult indicating success or failure.