Table of Contents

Class CharacterPetService

Namespace
FishMMO.Database.Npgsql.Services
Assembly
FishMMO-DB.dll

Service for managing character pet data in the database. Provides async operations for CRUD operations on character pet data. Implements execution strategies for automatic retry on transient database failures. Returns DatabaseResult for consistent, safe error handling.

public sealed class CharacterPetService : BaseService<CharacterPetEntity>, ICharacterPetService, IPersistAction<CharacterPetData>, IPersistManyAction<CharacterPetData>, IDeleteByKeyVersionedAction<long>, IFetchByKeyAction<long, CharacterPetData?>
Inheritance
CharacterPetService
Implements
Inherited Members

Remarks

This service manages character pet persistence including:

  • Pet save/update with atomic UPSERT operations
  • Pet spawn state management
  • Pet deletion (soft delete)
  • Pet retrieval (including spawned pet queries)
  • Pet attribute and buff data management

Database operations are executed via the BaseService execution wrappers for:

  • Automatic transient failure retry
  • Centralized exception handling and mapping
  • Consistent DatabaseResult pattern

When a write requires multiple database statements, it should be wrapped in ExecuteTransactionAsync(Func<NpgsqlDbContext, Task>, bool, string?, CancellationToken). Single-statement SQL operations (including CTE-based UPSERT/DELETE/UPDATE) are executed atomically without requiring an explicit transaction wrapper.

Constructors

CharacterPetService(INpgsqlDbContextFactory)

Initializes a new instance of the CharacterPetService class.

public CharacterPetService(INpgsqlDbContextFactory dbContextFactory)

Parameters

dbContextFactory INpgsqlDbContextFactory

Factory for creating database contexts.

Exceptions

ArgumentNullException

Thrown when dbContextFactory is null.

Methods

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

characterId long
incomingVersion long

The authoritative, monotonic version for this delete operation.

cancellationToken CancellationToken

Token to cancel the operation.

Returns

Task<DatabaseResult>

FetchAsync(long, CancellationToken)

Fetches an entity for the given key.

public Task<DatabaseResult<CharacterPetData?>> FetchAsync(long characterId, CancellationToken cancellationToken = default)

Parameters

characterId long
cancellationToken CancellationToken

Token to cancel the operation.

Returns

Task<DatabaseResult<CharacterPetData?>>

FetchSpawnedAsync(long, CancellationToken)

Fetches the spawned pet for the specified character.

public Task<DatabaseResult<CharacterPetData?>> FetchSpawnedAsync(long characterId, CancellationToken cancellationToken = default)

Parameters

characterId long

The character ID.

cancellationToken CancellationToken

Token to cancel the operation.

Returns

Task<DatabaseResult<CharacterPetData?>>

A DatabaseResult<T> containing the spawned pet on success, or null when not spawned.

PersistAsync(CharacterPetData, CancellationToken)

Persists the provided data.

public Task<DatabaseResult> PersistAsync(CharacterPetData petData, CancellationToken cancellationToken = default)

Parameters

petData CharacterPetData
cancellationToken CancellationToken

Token to cancel the operation.

Returns

Task<DatabaseResult>

PersistAsync(IEnumerable<CharacterPetData>, CancellationToken)

Persists the provided items.

public Task<DatabaseResult<BulkWriteResult>> PersistAsync(IEnumerable<CharacterPetData> pets, CancellationToken cancellationToken = default)

Parameters

pets IEnumerable<CharacterPetData>
cancellationToken CancellationToken

Token to cancel the operation.

Returns

Task<DatabaseResult<BulkWriteResult>>

What the write actually did, or a failure.

Remarks

A successful result does not mean every supplied row was written. Batched writes are version-gated and the service filters what it cannot act on, so the outcome carries counts rather than a bare boolean — see BulkWriteResult, which explains which discrepancies a caller should care about and which are routine.