Permalink
Browse files

Merge branch 'hotfix/4.0.2'

  • Loading branch information...
roji committed Jul 8, 2018
2 parents c442c87 + 7d5ad89 commit acba768a376357d43fafc70af4ee6d2de8fd70a1
@@ -1,5 +1,5 @@
image: Visual Studio 2017
version: 4.0.1-{build}
version: 4.0.2-{build}
environment:
global:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
@@ -41,6 +41,8 @@
Display="expand" >
<ComponentRef Id="Npgsql" />
<ComponentRef Id="System.Threading.Tasks.Extensions" />
<ComponentRef Id="System.ValueTuple" />
<ComponentRef Id="System.Runtime.CompilerServices.Unsafe" />
<ComponentRef Id="MachineConfig_x86" />
<ComponentRef Id="MachineConfig_x64" />
@@ -117,6 +119,20 @@
KeyPath="yes"
Assembly=".net" />
</Component>
<Component Id="System.ValueTuple" Guid="07cfe929-4a0c-4b90-87df-37cceaa970b8">
<File Id="System.ValueTuple"
Name="System.ValueTuple.dll"
Source="..\npgsql\bin\$(var.Configuration)\net451\System.ValueTuple.dll"
KeyPath="yes"
Assembly=".net" />
</Component>
<Component Id="System.Runtime.CompilerServices.Unsafe" Guid="36194b8d-d2af-4dd6-a9a0-fb6942502e53">
<File Id="System.Runtime.CompilerServices.Unsafe"
Name="System.Runtime.CompilerServices.Unsafe.dll"
Source="..\npgsql\bin\$(var.Configuration)\net451\System.Runtime.CompilerServices.Unsafe.dll"
KeyPath="yes"
Assembly=".net" />
</Component>
</Directory>
<!-- http://stackoverflow.com/questions/791455/how-do-i-modify-machine-config-via-an-msi-package -->
@@ -6,7 +6,7 @@
<Copyright>Copyright 2018 © The Npgsql Development Team</Copyright>
<Company>Npgsql</Company>
<PackageTags>npgsql postgresql postgres ado ado.net database sql</PackageTags>
<VersionPrefix>4.0.1</VersionPrefix>
<VersionPrefix>4.0.2</VersionPrefix>
<LangVersion>latest</LangVersion>
<TargetFrameworks>net45;net451;netstandard2.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@@ -1448,7 +1448,9 @@ void Cleanup()
ClearTransaction();
_stream = null;
_baseStream = null;
ReadBuffer?.AwaitableSocket?.Dispose();
ReadBuffer = null;
WriteBuffer?.AwaitableSocket?.Dispose();
WriteBuffer = null;
Connection = null;
PostgresParameters.Clear();
@@ -52,7 +52,7 @@ public sealed partial class NpgsqlReadBuffer
/// Wraps SocketAsyncEventArgs for better async I/O as long as we're not doing SSL.
/// </summary>
[CanBeNull]
internal AwaitableSocket AwaitableSocket { private get; set; }
internal AwaitableSocket AwaitableSocket { get; set; }
/// <summary>
/// The total byte length of the buffer.
@@ -50,7 +50,7 @@ public sealed partial class NpgsqlWriteBuffer
/// Wraps SocketAsyncEventArgs for better async I/O as long as we're not doing SSL.
/// </summary>
[CanBeNull]
internal AwaitableSocket AwaitableSocket { private get; set; }
internal AwaitableSocket AwaitableSocket { get; set; }
/// <summary>
/// The total byte length of the buffer.
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
using Npgsql.BackendMessages;
using Npgsql.PostgresTypes;
using Npgsql.TypeHandling;
using Npgsql.TypeMapping;
@@ -23,37 +24,23 @@ class MappedCompositeHandler<T> : NpgsqlTypeHandler<T>, IMappedCompositeHandler
{
readonly INpgsqlNameTranslator _nameTranslator;
readonly NpgsqlConnection _conn;
[CanBeNull]
UnmappedCompositeHandler _wrappedHandler;
readonly UnmappedCompositeHandler _wrappedHandler;
public Type CompositeType => typeof(T);
internal MappedCompositeHandler(INpgsqlNameTranslator nameTranslator, NpgsqlConnection conn)
internal MappedCompositeHandler(INpgsqlNameTranslator nameTranslator, PostgresType pgType, NpgsqlConnection conn)
{
PostgresType = pgType;
_nameTranslator = nameTranslator;
_conn = conn;
}
void WrapHandler()
{
_wrappedHandler = (UnmappedCompositeHandler)new UnmappedCompositeTypeHandlerFactory(_nameTranslator).Create(PostgresType, _conn);
}
public override ValueTask<T> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null)
{
if (_wrappedHandler == null)
WrapHandler();
Debug.Assert(_wrappedHandler != null);
return _wrappedHandler.Read<T>(buf, len, async, fieldDescription);
}
=> _wrappedHandler.Read<T>(buf, len, async, fieldDescription);
public override int ValidateAndGetLength(T value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter)
{
if (_wrappedHandler == null)
WrapHandler();
Debug.Assert(_wrappedHandler != null);
return _wrappedHandler.ValidateAndGetLength(value, ref lengthCache, parameter);
}
=> _wrappedHandler.ValidateAndGetLength(value, ref lengthCache, parameter);
public override Task Write(T value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
=> _wrappedHandler.Write(value, buf, lengthCache, parameter, async);
@@ -69,7 +56,10 @@ internal MappedCompositeTypeHandlerFactory(INpgsqlNameTranslator nameTranslator)
_nameTranslator = nameTranslator;
}
internal override NpgsqlTypeHandler Create(PostgresType pgType, NpgsqlConnection conn)
=> new MappedCompositeHandler<T>(_nameTranslator, pgType, conn);
protected override NpgsqlTypeHandler<T> Create(NpgsqlConnection conn)
=> new MappedCompositeHandler<T>(_nameTranslator, conn);
=> throw new InvalidOperationException($"Expect {nameof(PostgresType)}");
}
}
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
using Npgsql.BackendMessages;
using Npgsql.PostgresTypes;
using Npgsql.TypeHandling;
using Npgsql.TypeMapping;
@@ -23,37 +24,23 @@ class MappedEnumHandler<T> : NpgsqlTypeHandler<T>, IMappedEnumHandler where T :
{
readonly INpgsqlNameTranslator _nameTranslator;
readonly NpgsqlConnection _conn;
[CanBeNull]
UnmappedEnumHandler _wrappedHandler;
readonly UnmappedEnumHandler _wrappedHandler;
public Type EnumType => typeof(T);
internal MappedEnumHandler(INpgsqlNameTranslator nameTranslator, NpgsqlConnection conn)
internal MappedEnumHandler(INpgsqlNameTranslator nameTranslator, PostgresType pgType, NpgsqlConnection conn)
{
PostgresType = pgType;
_nameTranslator = nameTranslator;
_conn = conn;
}
void WrapHandler()
{
_wrappedHandler = (UnmappedEnumHandler)new UnmappedEnumTypeHandlerFactory(_nameTranslator).Create(PostgresType, _conn);
}
public override ValueTask<T> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null)
{
if (_wrappedHandler == null)
WrapHandler();
Debug.Assert(_wrappedHandler != null);
return _wrappedHandler.Read<T>(buf, len, async, fieldDescription);
}
=> _wrappedHandler.Read<T>(buf, len, async, fieldDescription);
public override int ValidateAndGetLength(T value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter)
{
if (_wrappedHandler == null)
WrapHandler();
Debug.Assert(_wrappedHandler != null);
return _wrappedHandler.ValidateAndGetLength(value, ref lengthCache, parameter);
}
=> _wrappedHandler.ValidateAndGetLength(value, ref lengthCache, parameter);
public override Task Write(T value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
=> _wrappedHandler.Write(value, buf, lengthCache, parameter, async);
@@ -69,7 +56,10 @@ internal MappedEnumTypeHandlerFactory(INpgsqlNameTranslator nameTranslator)
_nameTranslator = nameTranslator;
}
internal override NpgsqlTypeHandler Create(PostgresType pgType, NpgsqlConnection conn)
=> new MappedEnumHandler<T>(_nameTranslator, pgType, conn);
protected override NpgsqlTypeHandler<T> Create(NpgsqlConnection conn)
=> new MappedEnumHandler<T>(_nameTranslator, conn);
=> throw new InvalidOperationException($"Expect {nameof(PostgresType)}");
}
}
@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Npgsql.TypeHandlers.NumericHandlers
{
[StructLayout(LayoutKind.Explicit)]
struct DecimalRaw
{
const int SignMask = unchecked((int)0x80000000);
const int ScaleMask = 0x00FF0000;
const int ScaleShift = 16;
// Fast access for 10^n where n is 0-9
internal static readonly uint[] Powers10 = new uint[]
{
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000
};
// The maximum power of 10 that a 32 bit unsigned integer can store
internal static readonly int MaxUInt32Scale = Powers10.Length - 1;
// Do not change the order in which these fields are declared. It
// should be same as in the System.Decimal struct.
[FieldOffset(0)]
int _flags;
[FieldOffset(4)]
uint _high;
[FieldOffset(8)]
uint _low;
[FieldOffset(12)]
uint _mid;
public bool Negative => (_flags & SignMask) != 0;
public int Scale
{
get => (_flags & ScaleMask) >> ScaleShift;
set => _flags = (_flags & SignMask) | ((value << ScaleShift) & ScaleMask);
}
public uint High => _high;
public uint Mid => _mid;
public uint Low => _low;
public DecimalRaw(long value)
{
if (value >= 0)
_flags = 0;
else
{
_flags = SignMask;
value = -value;
}
_low = (uint)value;
_mid = (uint)(value >> 32);
_high = 0;
}
public static void Negate(ref DecimalRaw value)
=> value._flags ^= SignMask;
public static void Add(ref DecimalRaw value, uint addend)
{
uint integer;
uint sum;
integer = value._low;
value._low = sum = integer + addend;
if (sum >= integer && sum >= addend)
return;
integer = value._mid;
value._mid = sum = integer + 1;
if (sum >= integer && sum >= 1)
return;
integer = value._high;
value._high = sum = integer + 1;
if (sum < integer || sum < 1)
throw new OverflowException("Numeric value does not fit in a System.Decimal");
}
public static void Multiply(ref DecimalRaw value, uint multiplier)
{
ulong integer;
uint remainder;
integer = (ulong)value._low * multiplier;
value._low = (uint)integer;
remainder = (uint)(integer >> 32);
integer = (ulong)value._mid * multiplier + remainder;
value._mid = (uint)integer;
remainder = (uint)(integer >> 32);
integer = (ulong)value._high * multiplier + remainder;
value._high = (uint)integer;
remainder = (uint)(integer >> 32);
if (remainder != 0)
throw new OverflowException("Numeric value does not fit in a System.Decimal");
}
public static uint Divide(ref DecimalRaw value, uint divisor)
{
ulong integer;
uint remainder = 0;
if (value._high != 0)
{
integer = value._high;
value._high = (uint)(integer / divisor);
remainder = (uint)(integer % divisor);
}
if (value._mid != 0 || remainder != 0)
{
integer = ((ulong)remainder << 32) | value._mid;
value._mid = (uint)(integer / divisor);
remainder = (uint)(integer % divisor);
}
if (value._low != 0 || remainder != 0)
{
integer = ((ulong)remainder << 32) | value._low;
value._low = (uint)(integer / divisor);
remainder = (uint)(integer % divisor);
}
return remainder;
}
}
}
Oops, something went wrong.

0 comments on commit acba768

Please sign in to comment.