X Tutup
using System; using System.Data; using Npgsql; using Npgsql.Internal.Postgres; using static Npgsql.Util.Statics; #pragma warning disable CA1720 // ReSharper disable once CheckNamespace namespace NpgsqlTypes; /// /// Represents a PostgreSQL data type that can be written or read to the database. /// Used in places such as to unambiguously specify /// how to encode or decode values. /// /// /// See https://www.postgresql.org/docs/current/static/datatype.html. /// // Source for PG OIDs: public enum NpgsqlDbType { // Note that it's important to never change the numeric values of this enum, since user applications // compile them in. #region Numeric Types /// /// Corresponds to the PostgreSQL 8-byte "bigint" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-numeric.html Bigint = 1, /// /// Corresponds to the PostgreSQL 8-byte floating-point "double" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-numeric.html Double = 8, /// /// Corresponds to the PostgreSQL 4-byte "integer" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-numeric.html Integer = 9, /// /// Corresponds to the PostgreSQL arbitrary-precision "numeric" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-numeric.html Numeric = 13, /// /// Corresponds to the PostgreSQL floating-point "real" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-numeric.html Real = 17, /// /// Corresponds to the PostgreSQL 2-byte "smallint" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-numeric.html Smallint = 18, /// /// Corresponds to the PostgreSQL "money" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-money.html Money = 12, #endregion #region Boolean Type /// /// Corresponds to the PostgreSQL "boolean" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-boolean.html Boolean = 2, #endregion #region Geometric types /// /// Corresponds to the PostgreSQL geometric "box" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-geometric.html Box = 3, /// /// Corresponds to the PostgreSQL geometric "circle" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-geometric.html Circle = 5, /// /// Corresponds to the PostgreSQL geometric "line" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-geometric.html Line = 10, /// /// Corresponds to the PostgreSQL geometric "lseg" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-geometric.html LSeg = 11, /// /// Corresponds to the PostgreSQL geometric "path" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-geometric.html Path = 14, /// /// Corresponds to the PostgreSQL geometric "point" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-geometric.html Point = 15, /// /// Corresponds to the PostgreSQL geometric "polygon" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-geometric.html Polygon = 16, /// /// Corresponds to the PostgreSQL "cube" type, a geometric type representing multi-dimensional cubes. /// /// See https://www.postgresql.org/docs/current/cube.html Cube = 63, // Extension type #endregion #region Character Types /// /// Corresponds to the PostgreSQL "char(n)" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-character.html Char = 6, /// /// Corresponds to the PostgreSQL "text" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-character.html Text = 19, /// /// Corresponds to the PostgreSQL "varchar" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-character.html Varchar = 22, /// /// Corresponds to the PostgreSQL internal "name" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-character.html Name = 32, /// /// Corresponds to the PostgreSQL "citext" type for the citext module. /// /// See https://www.postgresql.org/docs/current/static/citext.html Citext = 51, // Extension type /// /// Corresponds to the PostgreSQL "char" type. /// /// /// This is an internal field and should normally not be used for regular applications. /// /// See https://www.postgresql.org/docs/current/static/datatype-text.html /// InternalChar = 38, #endregion #region Binary Data Types /// /// Corresponds to the PostgreSQL "bytea" type, holding a raw byte string. /// /// See https://www.postgresql.org/docs/current/static/datatype-binary.html Bytea = 4, #endregion #region Date/Time Types /// /// Corresponds to the PostgreSQL "date" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-datetime.html Date = 7, /// /// Corresponds to the PostgreSQL "time" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-datetime.html Time = 20, /// /// Corresponds to the PostgreSQL "timestamp" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-datetime.html Timestamp = 21, /// /// Corresponds to the PostgreSQL "timestamp with time zone" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-datetime.html TimestampTz = 26, /// /// Corresponds to the PostgreSQL "interval" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-datetime.html Interval = 30, /// /// Corresponds to the PostgreSQL "time with time zone" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-datetime.html TimeTz = 31, /// /// Corresponds to the obsolete PostgreSQL "abstime" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-datetime.html [Obsolete("The PostgreSQL abstime time is obsolete.")] Abstime = 33, #endregion #region Network Address Types /// /// Corresponds to the PostgreSQL "inet" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-net-types.html Inet = 24, /// /// Corresponds to the PostgreSQL "cidr" type, a field storing an IPv4 or IPv6 network. /// /// See https://www.postgresql.org/docs/current/static/datatype-net-types.html Cidr = 44, /// /// Corresponds to the PostgreSQL "macaddr" type, a field storing a 6-byte physical address. /// /// See https://www.postgresql.org/docs/current/static/datatype-net-types.html MacAddr = 34, /// /// Corresponds to the PostgreSQL "macaddr8" type, a field storing a 6-byte or 8-byte physical address. /// /// See https://www.postgresql.org/docs/current/static/datatype-net-types.html MacAddr8 = 54, #endregion #region Bit String Types /// /// Corresponds to the PostgreSQL "bit" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-bit.html Bit = 25, /// /// Corresponds to the PostgreSQL "varbit" type, a field storing a variable-length string of bits. /// /// See https://www.postgresql.org/docs/current/static/datatype-boolean.html Varbit = 39, #endregion #region Text Search Types /// /// Corresponds to the PostgreSQL "tsvector" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-textsearch.html TsVector = 45, /// /// Corresponds to the PostgreSQL "tsquery" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-textsearch.html TsQuery = 46, /// /// Corresponds to the PostgreSQL "regconfig" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-textsearch.html Regconfig = 56, #endregion #region UUID Type /// /// Corresponds to the PostgreSQL "uuid" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-uuid.html Uuid = 27, #endregion #region XML Type /// /// Corresponds to the PostgreSQL "xml" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-xml.html Xml = 28, #endregion #region JSON Types /// /// Corresponds to the PostgreSQL "json" type, a field storing JSON in text format. /// /// See https://www.postgresql.org/docs/current/static/datatype-json.html /// Json = 35, /// /// Corresponds to the PostgreSQL "jsonb" type, a field storing JSON in an optimized binary. /// format. /// /// /// Supported since PostgreSQL 9.4. /// See https://www.postgresql.org/docs/current/static/datatype-json.html /// Jsonb = 36, /// /// Corresponds to the PostgreSQL "jsonpath" type, a field storing JSON path in text format. /// format. /// /// /// Supported since PostgreSQL 12. /// See https://www.postgresql.org/docs/current/datatype-json.html#DATATYPE-JSONPATH /// JsonPath = 57, #endregion #region HSTORE Type /// /// Corresponds to the PostgreSQL "hstore" type, a dictionary of string key-value pairs. /// /// See https://www.postgresql.org/docs/current/static/hstore.html Hstore = 37, // Extension type #endregion #region Internal Types /// /// Corresponds to the PostgreSQL "refcursor" type. /// Refcursor = 23, /// /// Corresponds to the PostgreSQL internal "oidvector" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-oid.html Oidvector = 29, /// /// Corresponds to the PostgreSQL internal "int2vector" type. /// Int2Vector = 52, /// /// Corresponds to the PostgreSQL "oid" type. /// /// See https://www.postgresql.org/docs/current/static/datatype-oid.html Oid = 41, /// /// Corresponds to the PostgreSQL "xid" type, an internal transaction identifier. /// /// See https://www.postgresql.org/docs/current/static/datatype-oid.html Xid = 42, /// /// Corresponds to the PostgreSQL "xid8" type, an internal transaction identifier. /// /// See https://www.postgresql.org/docs/current/static/datatype-oid.html Xid8 = 64, /// /// Corresponds to the PostgreSQL "cid" type, an internal command identifier. /// /// See https://www.postgresql.org/docs/current/static/datatype-oid.html Cid = 43, /// /// Corresponds to the PostgreSQL "regtype" type, a numeric (OID) ID of a type in the pg_type table. /// Regtype = 49, /// /// Corresponds to the PostgreSQL "tid" type, a tuple id identifying the physical location of a row within its table. /// Tid = 53, /// /// Corresponds to the PostgreSQL "pg_lsn" type, which can be used to store LSN (Log Sequence Number) data which /// is a pointer to a location in the WAL. /// /// /// See: https://www.postgresql.org/docs/current/datatype-pg-lsn.html and /// https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=7d03a83f4d0736ba869fa6f93973f7623a27038a /// PgLsn = 59, #endregion #region Special /// /// A special value that can be used to send parameter values to the database without /// specifying their type, allowing the database to cast them to another value based on context. /// The value will be converted to a string and send as text. /// /// /// This value shouldn't ordinarily be used, and makes sense only when sending a data type /// unsupported by Npgsql. /// Unknown = 40, #endregion #region PostGIS /// /// The geometry type for PostgreSQL spatial extension PostGIS. /// Geometry = 50, // Extension type /// /// The geography (geodetic) type for PostgreSQL spatial extension PostGIS. /// Geography = 55, // Extension type #endregion #region Label tree types /// /// The PostgreSQL ltree type, each value is a label path "a.label.tree.value", forming a tree in a set. /// /// See https://www.postgresql.org/docs/current/static/ltree.html LTree = 60, // Extension type /// /// The PostgreSQL lquery type for PostgreSQL extension ltree /// /// See https://www.postgresql.org/docs/current/static/ltree.html LQuery = 61, // Extension type /// /// The PostgreSQL ltxtquery type for PostgreSQL extension ltree /// /// See https://www.postgresql.org/docs/current/static/ltree.html LTxtQuery = 62, // Extension type #endregion #region Range types /// /// Corresponds to the PostgreSQL "int4range" type. /// IntegerRange = Range | Integer, /// /// Corresponds to the PostgreSQL "int8range" type. /// BigIntRange = Range | Bigint, /// /// Corresponds to the PostgreSQL "numrange" type. /// NumericRange = Range | Numeric, /// /// Corresponds to the PostgreSQL "tsrange" type. /// TimestampRange = Range | Timestamp, /// /// Corresponds to the PostgreSQL "tstzrange" type. /// TimestampTzRange = Range | TimestampTz, /// /// Corresponds to the PostgreSQL "daterange" type. /// DateRange = Range | Date, #endregion Range types #region Multirange types /// /// Corresponds to the PostgreSQL "int4multirange" type. /// IntegerMultirange = Multirange | Integer, /// /// Corresponds to the PostgreSQL "int8multirange" type. /// BigIntMultirange = Multirange | Bigint, /// /// Corresponds to the PostgreSQL "nummultirange" type. /// NumericMultirange = Multirange | Numeric, /// /// Corresponds to the PostgreSQL "tsmultirange" type. /// TimestampMultirange = Multirange | Timestamp, /// /// Corresponds to the PostgreSQL "tstzmultirange" type. /// TimestampTzMultirange = Multirange | TimestampTz, /// /// Corresponds to the PostgreSQL "datemultirange" type. /// DateMultirange = Multirange | Date, #endregion Multirange types #region Composables /// /// Corresponds to the PostgreSQL "array" type, a variable-length multidimensional array of /// another type. This value must be combined with another value from /// via a bit OR (e.g. NpgsqlDbType.Array | NpgsqlDbType.Integer) /// /// See https://www.postgresql.org/docs/current/static/arrays.html Array = int.MinValue, /// /// Corresponds to the PostgreSQL "range" type, continuous range of values of specific type. /// This value must be combined with another value from /// via a bit OR (e.g. NpgsqlDbType.Range | NpgsqlDbType.Integer) /// /// /// Supported since PostgreSQL 9.2. /// See https://www.postgresql.org/docs/current/static/rangetypes.html /// Range = 0x40000000, /// /// Corresponds to the PostgreSQL "multirange" type, continuous range of values of specific type. /// This value must be combined with another value from /// via a bit OR (e.g. NpgsqlDbType.Multirange | NpgsqlDbType.Integer) /// /// /// Supported since PostgreSQL 14. /// See https://www.postgresql.org/docs/current/static/rangetypes.html /// Multirange = 0x20000000, #endregion } static class NpgsqlDbTypeExtensions { internal static NpgsqlDbType? ToNpgsqlDbType(this DbType dbType) => dbType switch { DbType.AnsiString => NpgsqlDbType.Text, DbType.Binary => NpgsqlDbType.Bytea, DbType.Byte => NpgsqlDbType.Smallint, DbType.Boolean => NpgsqlDbType.Boolean, DbType.Currency => NpgsqlDbType.Money, DbType.Date => NpgsqlDbType.Date, DbType.DateTime => LegacyTimestampBehavior ? NpgsqlDbType.Timestamp : NpgsqlDbType.TimestampTz, DbType.Decimal => NpgsqlDbType.Numeric, DbType.VarNumeric => NpgsqlDbType.Numeric, DbType.Double => NpgsqlDbType.Double, DbType.Guid => NpgsqlDbType.Uuid, DbType.Int16 => NpgsqlDbType.Smallint, DbType.Int32 => NpgsqlDbType.Integer, DbType.Int64 => NpgsqlDbType.Bigint, DbType.Single => NpgsqlDbType.Real, DbType.String => NpgsqlDbType.Text, DbType.Time => NpgsqlDbType.Time, DbType.AnsiStringFixedLength => NpgsqlDbType.Text, DbType.StringFixedLength => NpgsqlDbType.Text, DbType.Xml => NpgsqlDbType.Xml, DbType.DateTime2 => NpgsqlDbType.Timestamp, DbType.DateTimeOffset => NpgsqlDbType.TimestampTz, DbType.Object => null, DbType.SByte => null, DbType.UInt16 => null, DbType.UInt32 => null, DbType.UInt64 => null, _ => throw new ArgumentOutOfRangeException(nameof(dbType), dbType, null) }; public static DbType ToDbType(this NpgsqlDbType npgsqlDbType) => npgsqlDbType switch { // Numeric types NpgsqlDbType.Smallint => DbType.Int16, NpgsqlDbType.Integer => DbType.Int32, NpgsqlDbType.Bigint => DbType.Int64, NpgsqlDbType.Real => DbType.Single, NpgsqlDbType.Double => DbType.Double, NpgsqlDbType.Numeric => DbType.Decimal, NpgsqlDbType.Money => DbType.Currency, // Text types NpgsqlDbType.Text => DbType.String, NpgsqlDbType.Xml => DbType.Xml, NpgsqlDbType.Varchar => DbType.String, NpgsqlDbType.Char => DbType.String, NpgsqlDbType.Name => DbType.String, NpgsqlDbType.Citext => DbType.String, NpgsqlDbType.Refcursor => DbType.Object, NpgsqlDbType.Jsonb => DbType.Object, NpgsqlDbType.Json => DbType.Object, NpgsqlDbType.JsonPath => DbType.Object, // Date/time types NpgsqlDbType.Timestamp => LegacyTimestampBehavior ? DbType.DateTime : DbType.DateTime2, NpgsqlDbType.TimestampTz => LegacyTimestampBehavior ? DbType.DateTimeOffset : DbType.DateTime, NpgsqlDbType.Date => DbType.Date, NpgsqlDbType.Time => DbType.Time, // Misc data types NpgsqlDbType.Bytea => DbType.Binary, NpgsqlDbType.Boolean => DbType.Boolean, NpgsqlDbType.Uuid => DbType.Guid, NpgsqlDbType.Unknown => DbType.Object, _ => DbType.Object }; /// Can return null when a custom range type is used. internal static string? ToUnqualifiedDataTypeName(this NpgsqlDbType npgsqlDbType) => npgsqlDbType switch { // Numeric types NpgsqlDbType.Smallint => "int2", NpgsqlDbType.Integer => "int4", NpgsqlDbType.Bigint => "int8", NpgsqlDbType.Real => "float4", NpgsqlDbType.Double => "float8", NpgsqlDbType.Numeric => "numeric", NpgsqlDbType.Money => "money", // Text types NpgsqlDbType.Text => "text", NpgsqlDbType.Xml => "xml", NpgsqlDbType.Varchar => "varchar", NpgsqlDbType.Char => "bpchar", NpgsqlDbType.Name => "name", NpgsqlDbType.Refcursor => "refcursor", NpgsqlDbType.Jsonb => "jsonb", NpgsqlDbType.Json => "json", NpgsqlDbType.JsonPath => "jsonpath", // Date/time types NpgsqlDbType.Timestamp => "timestamp", NpgsqlDbType.TimestampTz => "timestamptz", NpgsqlDbType.Date => "date", NpgsqlDbType.Time => "time", NpgsqlDbType.TimeTz => "timetz", NpgsqlDbType.Interval => "interval", // Network types NpgsqlDbType.Cidr => "cidr", NpgsqlDbType.Inet => "inet", NpgsqlDbType.MacAddr => "macaddr", NpgsqlDbType.MacAddr8 => "macaddr8", // Full-text search types NpgsqlDbType.TsQuery => "tsquery", NpgsqlDbType.TsVector => "tsvector", // Geometry types NpgsqlDbType.Box => "box", NpgsqlDbType.Circle => "circle", NpgsqlDbType.Line => "line", NpgsqlDbType.LSeg => "lseg", NpgsqlDbType.Path => "path", NpgsqlDbType.Point => "point", NpgsqlDbType.Polygon => "polygon", // UInt types NpgsqlDbType.Oid => "oid", NpgsqlDbType.Xid => "xid", NpgsqlDbType.Xid8 => "xid8", NpgsqlDbType.Cid => "cid", NpgsqlDbType.Regtype => "regtype", NpgsqlDbType.Regconfig => "regconfig", // Misc types NpgsqlDbType.Boolean => "bool", NpgsqlDbType.Bytea => "bytea", NpgsqlDbType.Uuid => "uuid", NpgsqlDbType.Varbit => "varbit", NpgsqlDbType.Bit => "bit", // Built-in range types NpgsqlDbType.IntegerRange => "int4range", NpgsqlDbType.BigIntRange => "int8range", NpgsqlDbType.NumericRange => "numrange", NpgsqlDbType.TimestampRange => "tsrange", NpgsqlDbType.TimestampTzRange => "tstzrange", NpgsqlDbType.DateRange => "daterange", // Built-in multirange types NpgsqlDbType.IntegerMultirange => "int4multirange", NpgsqlDbType.BigIntMultirange => "int8multirange", NpgsqlDbType.NumericMultirange => "nummultirange", NpgsqlDbType.TimestampMultirange => "tsmultirange", NpgsqlDbType.TimestampTzMultirange => "tstzmultirange", NpgsqlDbType.DateMultirange => "datemultirange", // Internal types NpgsqlDbType.Int2Vector => "int2vector", NpgsqlDbType.Oidvector => "oidvector", NpgsqlDbType.PgLsn => "pg_lsn", NpgsqlDbType.Tid => "tid", NpgsqlDbType.InternalChar => "char", // Plugin types NpgsqlDbType.Citext => "citext", NpgsqlDbType.Cube => "cube", NpgsqlDbType.LQuery => "lquery", NpgsqlDbType.LTree => "ltree", NpgsqlDbType.LTxtQuery => "ltxtquery", NpgsqlDbType.Hstore => "hstore", NpgsqlDbType.Geometry => "geometry", NpgsqlDbType.Geography => "geography", NpgsqlDbType.Unknown => "unknown", // Unknown cannot be composed _ when npgsqlDbType.HasFlag(NpgsqlDbType.Array) && (npgsqlDbType & ~NpgsqlDbType.Array) == NpgsqlDbType.Unknown => "unknown", _ when npgsqlDbType.HasFlag(NpgsqlDbType.Range) && (npgsqlDbType & ~NpgsqlDbType.Range) == NpgsqlDbType.Unknown => "unknown", _ when npgsqlDbType.HasFlag(NpgsqlDbType.Multirange) && (npgsqlDbType & ~NpgsqlDbType.Multirange) == NpgsqlDbType.Unknown => "unknown", _ => npgsqlDbType.HasFlag(NpgsqlDbType.Array) ? ToUnqualifiedDataTypeName(npgsqlDbType & ~NpgsqlDbType.Array) is { } name ? "_" + name : null : null // e.g. ranges }; internal static string ToUnqualifiedDataTypeNameOrThrow(this NpgsqlDbType npgsqlDbType) => npgsqlDbType.ToUnqualifiedDataTypeName() ?? throw new ArgumentOutOfRangeException(nameof(npgsqlDbType), npgsqlDbType, "Cannot convert NpgsqlDbType to DataTypeName"); /// Can return null when a plugin type or custom range type is used. internal static DataTypeName? ToDataTypeName(this NpgsqlDbType npgsqlDbType) => npgsqlDbType switch { // Numeric types NpgsqlDbType.Smallint => DataTypeNames.Int2, NpgsqlDbType.Integer => DataTypeNames.Int4, NpgsqlDbType.Bigint => DataTypeNames.Int8, NpgsqlDbType.Real => DataTypeNames.Float4, NpgsqlDbType.Double => DataTypeNames.Float8, NpgsqlDbType.Numeric => DataTypeNames.Numeric, NpgsqlDbType.Money => DataTypeNames.Money, // Text types NpgsqlDbType.Text => DataTypeNames.Text, NpgsqlDbType.Xml => DataTypeNames.Xml, NpgsqlDbType.Varchar => DataTypeNames.Varchar, NpgsqlDbType.Char => DataTypeNames.Bpchar, NpgsqlDbType.Name => DataTypeNames.Name, NpgsqlDbType.Refcursor => DataTypeNames.RefCursor, NpgsqlDbType.Jsonb => DataTypeNames.Jsonb, NpgsqlDbType.Json => DataTypeNames.Json, NpgsqlDbType.JsonPath => DataTypeNames.Jsonpath, // Date/time types NpgsqlDbType.Timestamp => DataTypeNames.Timestamp, NpgsqlDbType.TimestampTz => DataTypeNames.TimestampTz, NpgsqlDbType.Date => DataTypeNames.Date, NpgsqlDbType.Time => DataTypeNames.Time, NpgsqlDbType.TimeTz => DataTypeNames.TimeTz, NpgsqlDbType.Interval => DataTypeNames.Interval, // Network types NpgsqlDbType.Cidr => DataTypeNames.Cidr, NpgsqlDbType.Inet => DataTypeNames.Inet, NpgsqlDbType.MacAddr => DataTypeNames.MacAddr, NpgsqlDbType.MacAddr8 => DataTypeNames.MacAddr8, // Full-text search types NpgsqlDbType.TsQuery => DataTypeNames.TsQuery, NpgsqlDbType.TsVector => DataTypeNames.TsVector, // Geometry types NpgsqlDbType.Box => DataTypeNames.Box, NpgsqlDbType.Circle => DataTypeNames.Circle, NpgsqlDbType.Line => DataTypeNames.Line, NpgsqlDbType.LSeg => DataTypeNames.LSeg, NpgsqlDbType.Path => DataTypeNames.Path, NpgsqlDbType.Point => DataTypeNames.Point, NpgsqlDbType.Polygon => DataTypeNames.Polygon, // UInt types NpgsqlDbType.Oid => DataTypeNames.Oid, NpgsqlDbType.Xid => DataTypeNames.Xid, NpgsqlDbType.Xid8 => DataTypeNames.Xid8, NpgsqlDbType.Cid => DataTypeNames.Cid, NpgsqlDbType.Regtype => DataTypeNames.RegType, NpgsqlDbType.Regconfig => DataTypeNames.RegConfig, // Misc types NpgsqlDbType.Boolean => DataTypeNames.Bool, NpgsqlDbType.Bytea => DataTypeNames.Bytea, NpgsqlDbType.Uuid => DataTypeNames.Uuid, NpgsqlDbType.Varbit => DataTypeNames.Varbit, NpgsqlDbType.Bit => DataTypeNames.Bit, // Built-in range types NpgsqlDbType.IntegerRange => DataTypeNames.Int4Range, NpgsqlDbType.BigIntRange => DataTypeNames.Int8Range, NpgsqlDbType.NumericRange => DataTypeNames.NumRange, NpgsqlDbType.TimestampRange => DataTypeNames.TsRange, NpgsqlDbType.TimestampTzRange => DataTypeNames.TsTzRange, NpgsqlDbType.DateRange => DataTypeNames.DateRange, // Internal types NpgsqlDbType.Int2Vector => DataTypeNames.Int2Vector, NpgsqlDbType.Oidvector => DataTypeNames.OidVector, NpgsqlDbType.PgLsn => DataTypeNames.PgLsn, NpgsqlDbType.Tid => DataTypeNames.Tid, NpgsqlDbType.InternalChar => DataTypeNames.Char, // Special types NpgsqlDbType.Unknown => DataTypeNames.Unknown, // Unknown cannot be composed _ when npgsqlDbType.HasFlag(NpgsqlDbType.Array) && (npgsqlDbType & ~NpgsqlDbType.Array) == NpgsqlDbType.Unknown => DataTypeNames.Unknown, _ when npgsqlDbType.HasFlag(NpgsqlDbType.Range) && (npgsqlDbType & ~NpgsqlDbType.Range) == NpgsqlDbType.Unknown => DataTypeNames.Unknown, _ when npgsqlDbType.HasFlag(NpgsqlDbType.Multirange) && (npgsqlDbType & ~NpgsqlDbType.Multirange) == NpgsqlDbType.Unknown => DataTypeNames.Unknown, // If both multirange and array are set we first remove array, so array is added to the outermost datatypename. _ when npgsqlDbType.HasFlag(NpgsqlDbType.Array) => ToDataTypeName(npgsqlDbType & ~NpgsqlDbType.Array)?.ToArrayName(), _ when npgsqlDbType.HasFlag(NpgsqlDbType.Multirange) => ToDataTypeName((npgsqlDbType | NpgsqlDbType.Range) & ~NpgsqlDbType.Multirange)?.ToDefaultMultirangeName(), // Plugin types don't have a stable fully qualified name. _ => null }; internal static NpgsqlDbType? ToNpgsqlDbType(this DataTypeName dataTypeName) => ToNpgsqlDbType(dataTypeName.UnqualifiedName); /// Should not be used with display names, first normalize it instead. internal static NpgsqlDbType? ToNpgsqlDbType(string normalizedDataTypeName) { var unqualifiedName = normalizedDataTypeName.AsSpan(); if (unqualifiedName.IndexOf('.') is not -1 and var index) unqualifiedName = unqualifiedName.Slice(index + 1); return unqualifiedName switch { // Numeric types "int2" => NpgsqlDbType.Smallint, "int4" => NpgsqlDbType.Integer, "int8" => NpgsqlDbType.Bigint, "float4" => NpgsqlDbType.Real, "float8" => NpgsqlDbType.Double, "numeric" => NpgsqlDbType.Numeric, "money" => NpgsqlDbType.Money, // Text types "text" => NpgsqlDbType.Text, "xml" => NpgsqlDbType.Xml, "varchar" => NpgsqlDbType.Varchar, "bpchar" => NpgsqlDbType.Char, "name" => NpgsqlDbType.Name, "refcursor" => NpgsqlDbType.Refcursor, "jsonb" => NpgsqlDbType.Jsonb, "json" => NpgsqlDbType.Json, "jsonpath" => NpgsqlDbType.JsonPath, // Date/time types "timestamp" => NpgsqlDbType.Timestamp, "timestamptz" => NpgsqlDbType.TimestampTz, "date" => NpgsqlDbType.Date, "time" => NpgsqlDbType.Time, "timetz" => NpgsqlDbType.TimeTz, "interval" => NpgsqlDbType.Interval, // Network types "cidr" => NpgsqlDbType.Cidr, "inet" => NpgsqlDbType.Inet, "macaddr" => NpgsqlDbType.MacAddr, "macaddr8" => NpgsqlDbType.MacAddr8, // Full-text search types "tsquery" => NpgsqlDbType.TsQuery, "tsvector" => NpgsqlDbType.TsVector, // Geometry types "box" => NpgsqlDbType.Box, "circle" => NpgsqlDbType.Circle, "line" => NpgsqlDbType.Line, "lseg" => NpgsqlDbType.LSeg, "path" => NpgsqlDbType.Path, "point" => NpgsqlDbType.Point, "polygon" => NpgsqlDbType.Polygon, // UInt types "oid" => NpgsqlDbType.Oid, "xid" => NpgsqlDbType.Xid, "xid8" => NpgsqlDbType.Xid8, "cid" => NpgsqlDbType.Cid, "regtype" => NpgsqlDbType.Regtype, "regconfig" => NpgsqlDbType.Regconfig, // Misc types "bool" => NpgsqlDbType.Boolean, "bytea" => NpgsqlDbType.Bytea, "uuid" => NpgsqlDbType.Uuid, "varbit" => NpgsqlDbType.Varbit, "bit" => NpgsqlDbType.Bit, // Built-in range types "int4range" => NpgsqlDbType.IntegerRange, "int8range" => NpgsqlDbType.BigIntRange, "numrange" => NpgsqlDbType.NumericRange, "tsrange" => NpgsqlDbType.TimestampRange, "tstzrange" => NpgsqlDbType.TimestampTzRange, "daterange" => NpgsqlDbType.DateRange, // Built-in multirange types "int4multirange" => NpgsqlDbType.IntegerMultirange, "int8multirange" => NpgsqlDbType.BigIntMultirange, "nummultirange" => NpgsqlDbType.NumericMultirange, "tsmultirange" => NpgsqlDbType.TimestampMultirange, "tstzmultirange" => NpgsqlDbType.TimestampTzMultirange, "datemultirange" => NpgsqlDbType.DateMultirange, // Internal types "int2vector" => NpgsqlDbType.Int2Vector, "oidvector" => NpgsqlDbType.Oidvector, "pg_lsn" => NpgsqlDbType.PgLsn, "tid" => NpgsqlDbType.Tid, "char" => NpgsqlDbType.InternalChar, // Plugin types "citext" => NpgsqlDbType.Citext, "cube" => NpgsqlDbType.Cube, "lquery" => NpgsqlDbType.LQuery, "ltree" => NpgsqlDbType.LTree, "ltxtquery" => NpgsqlDbType.LTxtQuery, "hstore" => NpgsqlDbType.Hstore, "geometry" => NpgsqlDbType.Geometry, "geography" => NpgsqlDbType.Geography, _ when unqualifiedName.IndexOf("unknown") != -1 => !unqualifiedName.StartsWith("_", StringComparison.Ordinal) ? NpgsqlDbType.Unknown : null, _ when unqualifiedName.StartsWith("_", StringComparison.Ordinal) => ToNpgsqlDbType(unqualifiedName.Slice(1).ToString()) is { } elementNpgsqlDbType ? elementNpgsqlDbType | NpgsqlDbType.Array : null, // e.g. custom ranges, plugin types etc. _ => null }; } }
X Tutup