using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Nodes;
using Npgsql.Internal;
using Npgsql.NameTranslation;
using NpgsqlTypes;
// ReSharper disable UnusedMember.Global
namespace Npgsql.TypeMapping;
///
/// A type mapper, managing how to read and write CLR values to PostgreSQL data types.
///
///
/// The preferred way to manage type mappings is on . An alternative, but discouraged, method, is to
/// manage them globally via ).
///
public interface INpgsqlTypeMapper
{
///
/// The default name translator to convert CLR type names and member names. Defaults to .
///
INpgsqlNameTranslator DefaultNameTranslator { get; set; }
///
/// Maps a CLR enum to a PostgreSQL enum type.
///
///
/// CLR enum labels are mapped by name to PostgreSQL enum labels.
/// The translation strategy can be controlled by the parameter,
/// which defaults to .
/// You can also use the on your enum fields to manually specify a PostgreSQL enum label.
/// If there is a discrepancy between the .NET and database labels while an enum is read or written,
/// an exception will be raised.
///
///
/// A PostgreSQL type name for the corresponding enum type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to .
///
/// The .NET enum type to be mapped
INpgsqlTypeMapper MapEnum<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TEnum>(
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null)
where TEnum : struct, Enum;
///
/// Removes an existing enum mapping.
///
///
/// A PostgreSQL type name for the corresponding enum type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to .
///
bool UnmapEnum<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TEnum>(
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null)
where TEnum : struct, Enum;
///
/// Maps a CLR enum to a PostgreSQL enum type.
///
///
/// CLR enum labels are mapped by name to PostgreSQL enum labels.
/// The translation strategy can be controlled by the parameter,
/// which defaults to .
/// You can also use the on your enum fields to manually specify a PostgreSQL enum label.
/// If there is a discrepancy between the .NET and database labels while an enum is read or written,
/// an exception will be raised.
///
/// The .NET enum type to be mapped
///
/// A PostgreSQL type name for the corresponding enum type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to .
///
[RequiresDynamicCode("Calling MapEnum with a Type can require creating new generic types or methods. This may not work when AOT compiling.")]
INpgsqlTypeMapper MapEnum(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]Type clrType,
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null);
///
/// Removes an existing enum mapping.
///
/// The .NET enum type to be mapped
///
/// A PostgreSQL type name for the corresponding enum type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to .
///
bool UnmapEnum(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]Type clrType,
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null);
///
/// Maps a CLR type to a PostgreSQL composite type.
///
///
/// CLR fields and properties by string to PostgreSQL names.
/// The translation strategy can be controlled by the parameter,
/// which defaults to .
/// You can also use the on your members to manually specify a PostgreSQL name.
/// If there is a discrepancy between the .NET type and database type while a composite is read or written,
/// an exception will be raised.
///
///
/// A PostgreSQL type name for the corresponding composite type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to .
///
/// The .NET type to be mapped
[RequiresDynamicCode("Mapping composite types involves serializing arbitrary types which can require creating new generic types or methods. This is currently unsupported with NativeAOT, vote on issue #5303 if this is important to you.")]
INpgsqlTypeMapper MapComposite<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] T>(
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null);
///
/// Removes an existing composite mapping.
///
///
/// A PostgreSQL type name for the corresponding composite type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to
///
[RequiresDynamicCode("Mapping composite types involves serializing arbitrary types which can require creating new generic types or methods. This is currently unsupported with NativeAOT, vote on issue #5303 if this is important to you.")]
bool UnmapComposite<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] T>(
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null);
///
/// Maps a CLR type to a composite type.
///
///
/// Maps CLR fields and properties by string to PostgreSQL names.
/// The translation strategy can be controlled by the parameter,
/// which defaults to .
/// If there is a discrepancy between the .NET type and database type while a composite is read or written,
/// an exception will be raised.
///
/// The .NET type to be mapped.
///
/// A PostgreSQL type name for the corresponding composite type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to .
///
[RequiresDynamicCode("Mapping composite types involves serializing arbitrary types which can require creating new generic types or methods. This is currently unsupported with NativeAOT, vote on issue #5303 if this is important to you.")]
INpgsqlTypeMapper MapComposite(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] Type clrType,
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null);
///
/// Removes an existing composite mapping.
///
/// The .NET type to be unmapped.
///
/// A PostgreSQL type name for the corresponding composite type in the database.
/// If null, the name translator given in will be used.
///
///
/// A component which will be used to translate CLR names (e.g. SomeClass) into database names (e.g. some_class).
/// Defaults to .
///
[RequiresDynamicCode("Mapping composite types involves serializing arbitrary types which can require creating new generic types or methods. This is currently unsupported with NativeAOT, vote on issue #5303 if this is important to you.")]
bool UnmapComposite(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] Type clrType,
string? pgName = null,
INpgsqlNameTranslator? nameTranslator = null);
///
/// Adds a type info resolver factory which can add or modify support for PostgreSQL types.
/// Typically used by plugins.
///
/// The type resolver factory to be added.
[Experimental(NpgsqlDiagnostics.ConvertersExperimental)]
void AddTypeInfoResolverFactory(PgTypeInfoResolverFactory factory);
///
/// Adds a DbType resolver factory which can change how DbType cases are mapped to PostgreSQL data types.
/// Typically used by plugins.
///
/// The resolver factory to be added.
[Experimental(NpgsqlDiagnostics.DbTypeResolverExperimental)]
public void AddDbTypeResolverFactory(DbTypeResolverFactory factory);
///
/// Configures the JSON serializer options used when reading and writing all System.Text.Json data.
///
/// Options to customize JSON serialization and deserialization.
///
INpgsqlTypeMapper ConfigureJsonOptions(JsonSerializerOptions serializerOptions);
///
/// Sets up dynamic System.Text.Json mappings. This allows mapping arbitrary .NET types to PostgreSQL json and jsonb
/// types, as well as and its derived types.
///
///
/// A list of CLR types to map to PostgreSQL jsonb (no need to specify ).
///
///
/// A list of CLR types to map to PostgreSQL json (no need to specify ).
///
///
/// Due to the dynamic nature of these mappings, they are not compatible with NativeAOT or trimming.
///
[RequiresUnreferencedCode("Json serializer may perform reflection on trimmed types.")]
[RequiresDynamicCode(
"Serializing arbitrary types to json can require creating new generic types or methods, which requires creating code at runtime. This may not work when AOT compiling.")]
INpgsqlTypeMapper EnableDynamicJson(Type[]? jsonbClrTypes = null, Type[]? jsonClrTypes = null);
///
/// Sets up mappings for the PostgreSQL record type as a .NET or .
///
/// The same builder instance so that multiple calls can be chained.
[RequiresUnreferencedCode(
"The mapping of PostgreSQL records as .NET tuples requires reflection usage which is incompatible with trimming.")]
[RequiresDynamicCode(
"The mapping of PostgreSQL records as .NET tuples requires dynamic code usage which is incompatible with NativeAOT.")]
INpgsqlTypeMapper EnableRecordsAsTuples();
///
/// Sets up mappings allowing the use of unmapped enum, range and multirange types.
///
/// The same builder instance so that multiple calls can be chained.
[RequiresUnreferencedCode(
"The use of unmapped enums, ranges or multiranges requires reflection usage which is incompatible with trimming.")]
[RequiresDynamicCode(
"The use of unmapped enums, ranges or multiranges requires dynamic code usage which is incompatible with NativeAOT.")]
INpgsqlTypeMapper EnableUnmappedTypes();
///
/// Resets all mapping changes performed on this type mapper and reverts it to its original, starting state.
///
void Reset();
}