Exemplo n.º 1
0
        void BindArrayType(NpgsqlTypeHandler elementHandler, PostgresArrayType pgArrayType, NpgsqlDbType?elementNpgsqlDbType, Type[] elementClrTypes)
        {
            var arrayHandler = elementHandler.CreateArrayHandler(pgArrayType);

            var arrayNpgsqlDbType = elementNpgsqlDbType.HasValue
                ? NpgsqlDbType.Array | elementNpgsqlDbType.Value
                : (NpgsqlDbType?)null;

            BindType(arrayHandler, pgArrayType, arrayNpgsqlDbType);

            // Note that array handlers aren't registered in ByClrType like base types, because they handle all
            // dimension types and not just one CLR type (e.g. int[], int[,], int[,,]).
            // So the by-type lookup is special and goes via _arrayHandlerByClrType, see this[Type type]
            // TODO: register single-dimensional in _byType as a specific optimization? But do PSV as well...
            if (elementClrTypes != null)
            {
                foreach (var elementType in elementClrTypes)
                {
                    if (_arrayHandlerByClrType.ContainsKey(elementType))
                    {
                        throw new Exception(
                                  $"Two array type handlers registered on same .NET type {elementType}: {_arrayHandlerByClrType[elementType].GetType().Name} and {arrayHandler.GetType().Name}");
                    }
                    _arrayHandlerByClrType[elementType] = arrayHandler;
                }
            }
        }
Exemplo n.º 2
0
 /// <inheritdoc />
 protected ArrayHandler(PostgresType arrayPostgresType, NpgsqlTypeHandler elementHandler, ArrayNullabilityMode arrayNullabilityMode, int lowerBound = 1)
     : base(arrayPostgresType)
 {
     LowerBound           = lowerBound;
     ElementHandler       = elementHandler;
     ArrayNullabilityMode = arrayNullabilityMode;
 }
 internal bool TryGetByOID(uint oid, out NpgsqlTypeHandler handler)
 {
     if (_byOID.TryGetValue(oid, out handler))
     {
         return(true);
     }
     // TODO: Late activation (composite/enum)
     return(false);
 }
Exemplo n.º 4
0
        internal static void ThrowInvalidCastException_NotSupportedType(NpgsqlTypeHandler handler, NpgsqlParameter?parameter, Type type)
        {
            var parameterName = parameter is null
                ? null
                : parameter.TrimmedName == string.Empty
                    ? $"${parameter.Collection!.IndexOf(parameter) + 1}"
                    : parameter.TrimmedName;

            throw new InvalidCastException(parameterName is null
                ? $"Cannot write a value of CLR type '{type}' as database type '{handler.PgDisplayName}'."
                : $"Cannot write a value of CLR type '{type}' as database type '{handler.PgDisplayName}' for parameter '{parameterName}'.");
        }
Exemplo n.º 5
0
        async ValueTask <T> DoRead <T>(NpgsqlTypeHandler handler, bool async)
        {
            try
            {
                await ReadColumnLenIfNeeded(async);

                if (_columnLen == -1)
                {
#pragma warning disable CS8653 // A default expression introduces a null value when 'T' is a non-nullable reference type.
                    // When T is a Nullable<T>, we support returning null
                    if (NullableHandler <T> .Exists)
                    {
                        return(default);
Exemplo n.º 6
0
        void BindType(NpgsqlTypeHandler handler, PostgresType pgType, NpgsqlDbType?npgsqlDbType = null, DbType[] dbTypes = null, Type[] clrTypes = null)
        {
            _byOID[pgType.OID]           = handler;
            _byTypeName[pgType.FullName] = handler;
            _byTypeName[pgType.Name]     = handler;

            if (npgsqlDbType.HasValue)
            {
                var value = npgsqlDbType.Value;
                if (_byNpgsqlDbType.ContainsKey(value))
                {
                    throw new InvalidOperationException($"Two type handlers registered on same NpgsqlDbType '{npgsqlDbType}': {_byNpgsqlDbType[value].GetType().Name} and {handler.GetType().Name}");
                }
                _byNpgsqlDbType[npgsqlDbType.Value] = handler;
            }

            if (dbTypes != null)
            {
                foreach (var dbType in dbTypes)
                {
                    if (_byDbType.ContainsKey(dbType))
                    {
                        throw new InvalidOperationException($"Two type handlers registered on same DbType {dbType}: {_byDbType[dbType].GetType().Name} and {handler.GetType().Name}");
                    }
                    _byDbType[dbType] = handler;
                }
            }

            if (clrTypes != null)
            {
                foreach (var type in clrTypes)
                {
                    if (_byClrType.ContainsKey(type))
                    {
                        throw new InvalidOperationException($"Two type handlers registered on same .NET type '{type}': {_byClrType[type].GetType().Name} and {handler.GetType().Name}");
                    }
                    _byClrType[type] = handler;
                }
            }

            if (pgType.Array != null)
            {
                BindArrayType(handler, pgType.Array, npgsqlDbType, clrTypes);
            }

            if (pgType.Range != null)
            {
                BindRangeType(handler, pgType.Range, npgsqlDbType, clrTypes);
            }
        }
Exemplo n.º 7
0
        public CompositeClassMemberHandler(FieldInfo fieldInfo, PostgresType postgresType, NpgsqlTypeHandler handler)
            : base(fieldInfo, postgresType)
        {
            var composite = Expression.Parameter(typeof(TComposite), "composite");
            var value     = Expression.Parameter(typeof(TMember), "value");

            _get = Expression
                   .Lambda <GetMember>(Expression.Field(composite, fieldInfo), composite)
                   .Compile();
            _set = Expression
                   .Lambda <SetMember>(Expression.Assign(Expression.Field(composite, fieldInfo), value), composite, value)
                   .Compile();
            _handler = handler;
        }
Exemplo n.º 8
0
        async ValueTask <T> DoRead <T>(NpgsqlTypeHandler handler, bool async, CancellationToken cancellationToken = default)
        {
            try
            {
                using var registration = _connector.StartNestedCancellableOperation(cancellationToken);

                await ReadColumnLenIfNeeded(async);

                if (_columnLen == -1)
                {
#pragma warning disable CS8653 // A default expression introduces a null value when 'T' is a non-nullable reference type.
                    // When T is a Nullable<T>, we support returning null
                    if (NullableHandler <T> .Exists)
                    {
                        return(default !);
Exemplo n.º 9
0
        void BindRangeType(NpgsqlTypeHandler elementHandler, PostgresRangeType pgRangeType, NpgsqlDbType?elementNpgsqlDbType, Type[]?elementClrTypes)
        {
            var rangeHandler = elementHandler.CreateRangeHandler(pgRangeType);

            var rangeNpgsqlDbType = elementNpgsqlDbType.HasValue
                ? NpgsqlDbType.Range | elementNpgsqlDbType.Value
                : (NpgsqlDbType?)null;

            // We only want to bind supported range CLR types whose element CLR types are being bound as well.
            var clrTypes = elementClrTypes is null
                ? null
                : rangeHandler.SupportedRangeClrTypes
                           .Where(r => elementClrTypes.Contains(r.GenericTypeArguments[0]))
                           .ToArray();

            BindType((NpgsqlTypeHandler)rangeHandler, pgRangeType, rangeNpgsqlDbType, null, clrTypes);
        }
Exemplo n.º 10
0
    internal NodaTimeTypeHandlerResolver(NpgsqlConnector connector)
    {
        _databaseInfo = connector.DatabaseInfo;

        _timestampHandler = LegacyTimestampBehavior
            ? new LegacyTimestampHandler(PgType("timestamp without time zone"))
            : new TimestampHandler(PgType("timestamp without time zone"));
        _timestampTzHandler = LegacyTimestampBehavior
            ? new LegacyTimestampTzHandler(PgType("timestamp with time zone"))
            : new TimestampTzHandler(PgType("timestamp with time zone"));
        _dateHandler     = new DateHandler(PgType("date"));
        _timeHandler     = new TimeHandler(PgType("time without time zone"));
        _timeTzHandler   = new TimeTzHandler(PgType("time with time zone"));
        _intervalHandler = new IntervalHandler(PgType("interval"));

        // Note that the range handlers are absent on some pseudo-PostgreSQL databases (e.g. CockroachDB), and multirange types
        // were only introduced in PG14. So we resolve these lazily.

        _arrayNullabilityMode = connector.Settings.ArrayNullabilityMode;
    }
Exemplo n.º 11
0
        public CompositeClassMemberHandler(PropertyInfo propertyInfo, PostgresType postgresType, NpgsqlTypeHandler handler)
            : base(propertyInfo, postgresType)
        {
            var getMethod = propertyInfo.GetGetMethod();

            if (getMethod != null)
            {
                _get = (GetMember)Delegate.CreateDelegate(typeof(GetMember), getMethod);
            }

            var setMethod = propertyInfo.GetSetMethod();

            if (setMethod != null)
            {
                _set = (SetMember)Delegate.CreateDelegate(typeof(SetMember), setMethod);
            }

            Debug.Assert(setMethod != null || getMethod != null);

            _handler = handler;
        }
Exemplo n.º 12
0
        void BindRangeType(NpgsqlTypeHandler elementHandler, PostgresRangeType pgRangeType, NpgsqlDbType?elementNpgsqlDbType, Type[] elementClrTypes)
        {
            var rangeHandler = elementHandler.CreateRangeHandler(pgRangeType);

            var rangeNpgsqlDbType = elementNpgsqlDbType.HasValue
                ? NpgsqlDbType.Range | elementNpgsqlDbType.Value
                : (NpgsqlDbType?)null;


            Type[] clrTypes = null;
            if (elementClrTypes != null)
            {
                // Somewhat hacky. Although the element may have more than one CLR mapping,
                // its range will only be mapped to the "main" one for now.
                var defaultElementType = elementHandler.GetFieldType();

                clrTypes = elementClrTypes.Contains(defaultElementType)
                    ? new[] { rangeHandler.GetFieldType() }
                    : null;
            }

            BindType(rangeHandler, pgRangeType, rangeNpgsqlDbType, null, clrTypes);
        }
Exemplo n.º 13
0
        T DoRead <T>(NpgsqlTypeHandler handler)
        {
            try {
                ReadColumnLenIfNeeded();
                if (_columnLen == -1)
                {
                    throw new InvalidCastException("Column is null");
                }

                // If we know the entire column is already in memory, use the code path without async
                var result = _columnLen <= _buf.ReadBytesLeft
                    ? handler.Read <T>(_buf, _columnLen)
                    : handler.Read <T>(_buf, _columnLen, false).GetAwaiter().GetResult();

                _leftToReadInDataMsg -= _columnLen;
                _columnLen            = int.MinValue; // Mark that the (next) column length hasn't been read yet
                _column++;
                return(result);
            } catch {
                _connector.Break();
                Cleanup();
                throw;
            }
        }
 public DateRangeHandler(PostgresType rangePostgresType, NpgsqlTypeHandler subtypeHandler)
     : base(rangePostgresType, subtypeHandler)
 {
 }
Exemplo n.º 15
0
 public CompositeParameterHandler(NpgsqlTypeHandler handler, ParameterInfo parameterInfo)
 {
     Handler           = handler;
     ParameterType     = parameterInfo.ParameterType;
     ParameterPosition = parameterInfo.Position;
 }
Exemplo n.º 16
0
 internal bool TryGetByOID(uint oid, out NpgsqlTypeHandler handler)
 => _byOID.TryGetValue(oid, out handler);
Exemplo n.º 17
0
 /// <inheritdoc />
 protected ArrayHandler(PostgresType arrayPostgresType, NpgsqlTypeHandler elementHandler, int lowerBound = 1)
     : base(arrayPostgresType)
 {
     LowerBound     = lowerBound;
     ElementHandler = elementHandler;
 }
Exemplo n.º 18
0
 public ColumnInfo(uint typeOid, int bufferPos, NpgsqlTypeHandler typeHandler)
 {
     TypeOid     = typeOid;
     BufferPos   = bufferPos;
     TypeHandler = typeHandler;
 }
Exemplo n.º 19
0
 public ArrayHandlerWithPsv(NpgsqlTypeHandler elementHandler)
     : base(elementHandler)
 {
 }
Exemplo n.º 20
0
 /// <inheritdoc />
 public RangeHandler(PostgresType rangePostgresType, NpgsqlTypeHandler subtypeHandler)
     : base(rangePostgresType)
     => SubtypeHandler = subtypeHandler;
Exemplo n.º 21
0
 /// <inheritdoc />
 protected RangeHandler(PostgresType rangePostgresType, NpgsqlTypeHandler elementHandler, Type[] supportedElementClrTypes)
     : base(rangePostgresType)
 {
     _elementHandler        = elementHandler;
     SupportedRangeClrTypes = supportedElementClrTypes;
 }
 public CrateDbObjectArrayHandler(NpgsqlTypeHandler elementHandler)
     : base(elementHandler)
 {
 }
Exemplo n.º 23
0
 public RangeHandler(NpgsqlTypeHandler <TElement> elementHandler)
 {
     ElementHandler = elementHandler;
 }
Exemplo n.º 24
0
 /// <inheritdoc />
 public RangeHandler(PostgresType rangePostgresType, NpgsqlTypeHandler subtypeHandler)
     : this(rangePostgresType, subtypeHandler, new[] { typeof(NpgsqlRange <TElement>) })
 {
 }
Exemplo n.º 25
0
 public CompositeParameterHandler(NpgsqlTypeHandler handler, ParameterInfo parameterInfo)
     : base(handler, parameterInfo)
 {
 }
Exemplo n.º 26
0
 /// <inheritdoc />
 protected RangeHandler(PostgresType rangePostgresType, NpgsqlTypeHandler subtypeHandler, Type[] supportedSubtypeClrTypes)
 {
     PostgresType           = rangePostgresType;
     _subtypeHandler        = subtypeHandler;
     SupportedRangeClrTypes = supportedSubtypeClrTypes;
 }
Exemplo n.º 27
0
 internal void ResolveHandler()
 => Handler = IsBinaryFormat ? _typeMapper.GetByOID(TypeOID) : _typeMapper.UnrecognizedTypeHandler;
Exemplo n.º 28
0
 public TimestampTzRangeHandler(PostgresType rangePostgresType, NpgsqlTypeHandler subtypeHandler)
     : base(rangePostgresType, subtypeHandler)
 {
 }