Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

BigDecimal type is now fully tested and intigrated into to FluentCass…

…andra
  • Loading branch information...
commit 65b37284392ba66aaea9666dde8d84860952233a 1 parent a80fb8c
@nberardi nberardi authored
View
4 src/Operations/InsertColumn.cs
@@ -32,10 +32,10 @@ public override Void Execute()
};
if (SuperColumnName != null)
- parent.SuperColumn = SuperColumnName.GetValue(schema.SuperColumnNameType) as CassandraObject;
+ parent.SuperColumn = SuperColumnName.GetValue(schema.SuperColumnNameType);
var column = new CassandraColumn {
- Name = ColumnName.GetValue(schema.ColumnNameType) as CassandraObject,
+ Name = ColumnName.GetValue(schema.ColumnNameType),
Value = ColumnValue,
Timestamp = Timestamp,
Ttl = TimeToLive
View
24 src/System/Numerics/BigDecimal.cs
@@ -29,7 +29,10 @@ public BigDecimal(decimal value)
Array.Copy(bytes, unscaledValueBytes, unscaledValueBytes.Length);
var unscaledValue = new BigInteger(unscaledValueBytes);
- var scale = BitConverter.ToInt32(bytes, 12);
+ var scale = bytes[14];
+
+ if (bytes[15] == 128)
+ unscaledValue *= BigInteger.MinusOne;
_unscaledValue = unscaledValue;
_scale = scale;
@@ -71,6 +74,16 @@ public BigDecimal(byte[] value)
public bool IsZero { get { return _unscaledValue.IsZero; } }
public int Sign { get { return _unscaledValue.Sign; } }
+ public override string ToString()
+ {
+ var number = _unscaledValue.ToString("G");
+
+ if (_scale > 0)
+ return number.Insert(number.Length - _scale, ".");
+
+ return number;
+ }
+
public byte[] ToByteArray()
{
var unscaledValue = _unscaledValue.ToByteArray();
@@ -78,7 +91,7 @@ public byte[] ToByteArray()
var bytes = new byte[unscaledValue.Length + scale.Length];
Array.Copy(unscaledValue, 0, bytes, 0, unscaledValue.Length);
- Array.Copy(scale, 0, bytes, unscaledValue.Length, bytes.Length);
+ Array.Copy(scale, 0, bytes, unscaledValue.Length, scale.Length);
return bytes;
}
@@ -220,6 +233,12 @@ private static byte[] FromDecimal(decimal d)
public static explicit operator float(BigDecimal value) { return value.ToType<float>(); }
public static explicit operator double(BigDecimal value) { return value.ToType<double>(); }
public static explicit operator decimal(BigDecimal value) { return value.ToType<decimal>(); }
+ public static explicit operator BigInteger(BigDecimal value)
+ {
+ var scaleDivisor = BigInteger.Pow(new BigInteger(10), value._scale);
+ var scaledValue = BigInteger.Divide(value._unscaledValue, scaleDivisor);
+ return scaledValue;
+ }
public static implicit operator BigDecimal(byte value) { return new BigDecimal(value); }
public static implicit operator BigDecimal(sbyte value) { return new BigDecimal(value); }
@@ -232,6 +251,7 @@ private static byte[] FromDecimal(decimal d)
public static implicit operator BigDecimal(float value) { return new BigDecimal(value); }
public static implicit operator BigDecimal(double value) { return new BigDecimal(value); }
public static implicit operator BigDecimal(decimal value) { return new BigDecimal(value); }
+ public static implicit operator BigDecimal(BigInteger value) { return new BigDecimal(value, 0); }
#endregion
View
41 src/Types/BytesTypeConverter.cs
@@ -26,6 +26,9 @@ public override bool CanConvertFrom(Type sourceType)
if (sourceType == typeof(BigInteger))
return true;
+ if (sourceType == typeof(BigDecimal))
+ return true;
+
switch (Type.GetTypeCode(sourceType))
{
case TypeCode.Byte:
@@ -67,6 +70,9 @@ public override bool CanConvertTo(Type destinationType)
if (destinationType == typeof(BigInteger))
return true;
+ if (destinationType == typeof(BigDecimal))
+ return true;
+
switch (Type.GetTypeCode(destinationType))
{
case TypeCode.Byte:
@@ -260,41 +266,18 @@ public byte[] FromBigEndian(byte[] value, Type destinationType)
private static byte[] FromDecimal(decimal d)
{
- byte[] bytes = new byte[16];
-
- int[] bits = decimal.GetBits(d);
- int lo = bits[0];
- int mid = bits[1];
- int hi = bits[2];
- int flags = bits[3];
-
- bytes[0] = (byte)lo;
- bytes[1] = (byte)(lo >> 8);
- bytes[2] = (byte)(lo >> 0x10);
- bytes[3] = (byte)(lo >> 0x18);
- bytes[4] = (byte)mid;
- bytes[5] = (byte)(mid >> 8);
- bytes[6] = (byte)(mid >> 0x10);
- bytes[7] = (byte)(mid >> 0x18);
- bytes[8] = (byte)hi;
- bytes[9] = (byte)(hi >> 8);
- bytes[10] = (byte)(hi >> 0x10);
- bytes[11] = (byte)(hi >> 0x18);
- bytes[12] = (byte)flags;
- bytes[13] = (byte)(flags >> 8);
- bytes[14] = (byte)(flags >> 0x10);
- bytes[15] = (byte)(flags >> 0x18);
-
- return bytes;
+ // we are now always saving byte arrays in BigDecimal format since they are often more compact than the .NET Decimal Type
+ var bigDecimal = new BigDecimal(d);
+ return bigDecimal.ToByteArray();
}
private static decimal ToDecimal(byte[] bytes)
{
if (bytes.Length != 16)
- return FromJavaBigDecimalToDecimal(bytes);
+ return FromBigDecimalToDecimal(bytes);
try { return FromDotNetDecimalToDecimal(bytes); }
- catch { return FromJavaBigDecimalToDecimal(bytes); }
+ catch { return FromBigDecimalToDecimal(bytes); }
}
private static decimal FromDotNetDecimalToDecimal(byte[] bytes)
@@ -308,7 +291,7 @@ private static decimal FromDotNetDecimalToDecimal(byte[] bytes)
return new decimal(bits);
}
- private static decimal FromJavaBigDecimalToDecimal(byte[] bytes)
+ private static decimal FromBigDecimalToDecimal(byte[] bytes)
{
var bigDec = new BigDecimal(bytes);
return (decimal)bigDec;
View
9 src/Types/CassandraConversionHelper.cs
@@ -1,4 +1,5 @@
using System;
+using System.Numerics;
namespace FluentCassandra.Types
{
@@ -53,5 +54,13 @@ internal static Guid ToGuidFromBigEndianBytes(this byte[] value)
ReverseHighFieldTimestamp(buffer);
return new Guid(buffer);
}
+
+ internal static BigDecimal ToBigDecimalFromBigEndianBytes(this byte[] value)
+ {
+ var buffer = (byte[])value.Clone();
+ Array.Reverse(buffer);
+
+ return new BigDecimal(buffer);
+ }
}
}
View
74 src/Types/DecimalTypeConverter.cs
@@ -7,18 +7,46 @@ internal class DecimalTypeConverter : CassandraObjectConverter<BigDecimal>
{
public override bool CanConvertFrom(Type sourceType)
{
- if (Type.GetTypeCode(sourceType) != TypeCode.Object)
- return true;
+ switch (Type.GetTypeCode(sourceType))
+ {
+ case TypeCode.Byte:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ case TypeCode.Int64:
+ case TypeCode.SByte:
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ case TypeCode.UInt64:
+ case TypeCode.Single:
+ case TypeCode.Double:
+ case TypeCode.Decimal:
+ return true;
- return sourceType == typeof(byte[]);
+ default:
+ return sourceType == typeof(byte[]) || sourceType == typeof(BigInteger) || sourceType == typeof(BigDecimal);
+ }
}
public override bool CanConvertTo(Type destinationType)
{
- if (Type.GetTypeCode(destinationType) != TypeCode.Object)
- return true;
+ switch (Type.GetTypeCode(destinationType))
+ {
+ case TypeCode.Byte:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ case TypeCode.Int64:
+ case TypeCode.SByte:
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ case TypeCode.UInt64:
+ case TypeCode.Single:
+ case TypeCode.Double:
+ case TypeCode.Decimal:
+ return true;
- return destinationType == typeof(byte[]);
+ default:
+ return destinationType == typeof(byte[]) || destinationType == typeof(BigInteger) || destinationType == typeof(BigDecimal);
+ }
}
public override BigDecimal ConvertFromInternal(object value)
@@ -26,7 +54,22 @@ public override BigDecimal ConvertFromInternal(object value)
if (value is byte[])
return ((byte[])value).FromBytes<BigDecimal>();
- return (BigDecimal)Convert.ChangeType(value, typeof(BigDecimal));
+ if (value is BigDecimal) return (BigDecimal)value;
+
+ if (value is byte) return (BigDecimal)(byte)value;
+ if (value is short) return (BigDecimal)(short)value;
+ if (value is int) return (BigDecimal)(int)value;
+ if (value is long) return (BigDecimal)(long)value;
+ if (value is sbyte) return (BigDecimal)(sbyte)value;
+ if (value is ushort) return (BigDecimal)(ushort)value;
+ if (value is uint) return (BigDecimal)(uint)value;
+ if (value is ulong) return (BigDecimal)(ulong)value;
+ if (value is float) return (BigDecimal)(float)value;
+ if (value is double) return (BigDecimal)(double)value;
+ if (value is decimal) return (BigDecimal)(decimal)value;
+ if (value is BigInteger) return (BigDecimal)(BigInteger)value;
+
+ return default(BigDecimal);
}
public override object ConvertToInternal(BigDecimal value, Type destinationType)
@@ -34,7 +77,22 @@ public override object ConvertToInternal(BigDecimal value, Type destinationType)
if (destinationType == typeof(byte[]))
return value.ToBytes();
- return Convert.ChangeType(value, destinationType);
+ if (destinationType == typeof(BigDecimal)) return value;
+
+ if (destinationType == typeof(byte)) return (byte)value;
+ if (destinationType == typeof(short)) return (short)value;
+ if (destinationType == typeof(int)) return (int)value;
+ if (destinationType == typeof(long)) return (long)value;
+ if (destinationType == typeof(sbyte)) return (sbyte)value;
+ if (destinationType == typeof(ushort)) return (ushort)value;
+ if (destinationType == typeof(uint)) return (uint)value;
+ if (destinationType == typeof(ulong)) return (ulong)value;
+ if (destinationType == typeof(float)) return (float)value;
+ if (destinationType == typeof(double)) return (double)value;
+ if (destinationType == typeof(decimal)) return (decimal)value;
+ if (destinationType == typeof(BigInteger)) return (BigInteger)value;
+
+ return null;
}
}
}
View
2  test/FluentCassandra.Tests/Bugs/Issue25JavaBigDecimalBinaryConversion.cs
@@ -20,7 +20,7 @@ public void Dispose()
_db.Dispose();
}
- [Fact(Skip="Need to work on later")]
+ [Fact]
public void Test()
{
// arrange
View
1  test/FluentCassandra.Tests/FluentCassandra.Tests.csproj
@@ -49,6 +49,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="BigDecimalTest.cs" />
<Compile Include="Bugs\Issue25JavaBigDecimalBinaryConversion.cs" />
<Compile Include="CassandraDatabaseSetupFixture.cs" />
<Compile Include="CassandraQueryTest.cs" />
Please sign in to comment.
Something went wrong with that request. Please try again.