X Tutup
using System; using Npgsql.Internal.Postgres; namespace Npgsql.PostgresTypes; /// /// Represents a PostgreSQL data type, such as int4 or text, as discovered from pg_type. /// This class is abstract, see derived classes for concrete types of PostgreSQL types. /// /// /// Instances of this class are shared between connections to the same databases. /// For more info about what this class and its subclasses represent, see /// https://www.postgresql.org/docs/current/static/catalog-pg-type.html. /// public abstract class PostgresType { #region Constructors /// /// Constructs a representation of a PostgreSQL data type. /// /// The data type's namespace (or schema). /// The data type's name. /// The data type's OID. private protected PostgresType(string ns, string name, uint oid) { DataTypeName = DataTypeName.FromDisplayName(name, ns, assumeUnqualified: true); OID = oid; FullName = Namespace + "." + Name; } /// /// Constructs a representation of a PostgreSQL data type. /// /// The data type's fully qualified name. /// The data type's OID. private protected PostgresType(DataTypeName dataTypeName, Oid oid) { DataTypeName = dataTypeName; OID = oid.Value; FullName = Namespace + "." + Name; } #endregion #region Public Properties /// /// The data type's OID - a unique id identifying the data type in a given database (in pg_type). /// public uint OID { get; } /// /// The data type's namespace (or schema). /// public string Namespace => DataTypeName.Schema; /// /// The data type's name. /// /// /// Note that this is the standard, user-displayable type name (e.g. integer[]) rather than the internal /// PostgreSQL name as it is in pg_type (_int4). See for the latter. /// public string Name => DataTypeName.UnqualifiedDisplayName; /// /// The full name of the backend type, including its namespace. /// public string FullName { get; } internal DataTypeName DataTypeName { get; } /// /// A display name for this backend type, including the namespace unless it is pg_catalog (the namespace /// for all built-in types). /// public string DisplayName => DataTypeName.DisplayName; /// /// The data type's internal PostgreSQL name (e.g. _int4 not integer[]). /// See for a more user-friendly name. /// public string InternalName => DataTypeName.UnqualifiedName; /// /// If a PostgreSQL array type exists for this type, it will be referenced here. /// Otherwise null. /// public PostgresArrayType? Array { get; internal set; } /// /// If a PostgreSQL range type exists for this type, it will be referenced here. /// Otherwise null. /// public PostgresRangeType? Range { get; internal set; } #endregion internal virtual string GetPartialNameWithFacets(int typeModifier) => Name; /// /// Generates the type name including any facts (size, precision, scale), given the PostgreSQL type modifier. /// internal string GetDisplayNameWithFacets(int typeModifier) => Namespace == "pg_catalog" ? GetPartialNameWithFacets(typeModifier) : Namespace + '.' + GetPartialNameWithFacets(typeModifier); internal virtual PostgresFacets GetFacets(int typeModifier) => PostgresFacets.None; /// /// Returns a string that represents the current object. /// public override string ToString() => DisplayName; PostgresType? _representationalType; /// Canonizes (nested) domain types to underlying types, does not handle composites. internal PostgresType GetRepresentationalType() { return _representationalType ??= Core(this) ?? throw new InvalidOperationException("Couldn't map type to representational type"); static PostgresType? Core(PostgresType? postgresType) => (postgresType as PostgresDomainType)?.BaseType ?? postgresType switch { PostgresArrayType { Element: PostgresDomainType domain } => Core(domain.BaseType)?.Array, PostgresMultirangeType { Subrange.Subtype: PostgresDomainType domain } => domain.BaseType.Range?.Multirange, PostgresRangeType { Subtype: PostgresDomainType domain } => domain.Range, var type => type }; } }
X Tutup