Skip to content
Browse files

corrected DecimalType byte array for Big Endian support in Java to co…

…rrect

issue #83
  • Loading branch information...
1 parent 2054160 commit d05b40e1a58f2a6c466c71bd51232d5272938512 @nberardi nberardi committed Nov 4, 2012
View
3 src/System/Numerics/BigDecimal.cs
@@ -71,6 +71,9 @@ public BigDecimal(byte[] value)
public bool IsZero { get { return _unscaledValue.IsZero; } }
public int Sign { get { return _unscaledValue.Sign; } }
+ public BigInteger UnscaledValue { get { return _unscaledValue; } }
+ public int Scale { get { return _scale; } }
+
public override string ToString()
{
var number = _unscaledValue.ToString("G");
View
8 src/Types/CassandraConversionHelper.cs
@@ -54,13 +54,5 @@ 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
3 src/Types/CassandraObject.cs
@@ -120,6 +120,7 @@ private static CassandraObject ConvertFrom(object o)
public static implicit operator CassandraObject(DateTime o) { return ConvertFrom(o); }
public static implicit operator CassandraObject(DateTimeOffset o) { return ConvertFrom(o); }
public static implicit operator CassandraObject(BigInteger o) { return ConvertFrom(o); }
+ public static implicit operator CassandraObject(BigDecimal o) { return ConvertFrom(o); }
public static implicit operator byte[](CassandraObject o) { return ConvertTo<byte[]>(o); }
public static implicit operator char[](CassandraObject o) { return ConvertTo<char[]>(o); }
@@ -142,6 +143,7 @@ private static CassandraObject ConvertFrom(object o)
public static implicit operator DateTime(CassandraObject o) { return ConvertTo<DateTime>(o); }
public static implicit operator DateTimeOffset(CassandraObject o) { return ConvertTo<DateTimeOffset>(o); }
public static implicit operator BigInteger(CassandraObject o) { return ConvertTo<BigInteger>(o); }
+ public static implicit operator BigDecimal(CassandraObject o) { return ConvertTo<BigDecimal>(o); }
public static implicit operator byte?(CassandraObject o) { return ConvertTo<byte?>(o); }
public static implicit operator sbyte?(CassandraObject o) { return ConvertTo<sbyte?>(o); }
@@ -161,6 +163,7 @@ private static CassandraObject ConvertFrom(object o)
public static implicit operator DateTime?(CassandraObject o) { return ConvertTo<DateTime?>(o); }
public static implicit operator DateTimeOffset?(CassandraObject o) { return ConvertTo<DateTimeOffset?>(o); }
public static implicit operator BigInteger?(CassandraObject o) { return ConvertTo<BigInteger?>(o); }
+ public static implicit operator BigDecimal?(CassandraObject o) { return ConvertTo<BigDecimal?>(o); }
public static explicit operator object[](CassandraObject o) { return ConvertTo<object[]>(o); }
public static explicit operator List<object>(CassandraObject o) { return ConvertTo<List<object>>(o); }
View
36 src/Types/DecimalTypeConverter.cs
@@ -94,5 +94,41 @@ public override object ConvertToInternal(BigDecimal value, Type destinationType)
return null;
}
+
+ public override byte[] ToBigEndian(BigDecimal value)
+ {
+ var scale = value.Scale;
+ var number = value.UnscaledValue;
+
+ var int32Converter = new Int32TypeConverter();
+ var bigIntegerConverter = new IntegerTypeConverter();
+
+ var scaleBytes = int32Converter.ToBigEndian(scale);
+ var numberBytes = bigIntegerConverter.ToBigEndian(number);
+
+ var bytes = new byte[scaleBytes.Length + numberBytes.Length];
+
+ Array.Copy(scaleBytes, 0, bytes, 0, scaleBytes.Length);
+ Array.Copy(numberBytes, 0, bytes, scaleBytes.Length, numberBytes.Length);
+
+ return bytes;
+ }
+
+ public override BigDecimal FromBigEndian(byte[] value)
+ {
+ var scaleBytes = new byte[4];
+ var numberBytes = new byte[value.Length - 4];
+
+ Array.Copy(value, 0, scaleBytes, 0, scaleBytes.Length);
+ Array.Copy(value, scaleBytes.Length, numberBytes, 0, numberBytes.Length);
+
+ var int32Converter = new Int32TypeConverter();
+ var bigIntegerConverter = new IntegerTypeConverter();
+
+ var scale = int32Converter.FromBigEndian(scaleBytes);
+ var number = bigIntegerConverter.FromBigEndian(numberBytes);
+
+ return new BigDecimal(number, scale);
+ }
}
}
View
4 test/FluentCassandra.Tests/CassandraDatabaseSetup.cs
@@ -83,6 +83,10 @@ public void ResetDatabase()
keyspace.TryCreateColumnFamily<UTF8Type>("StandardUTF8Type");
keyspace.TryCreateColumnFamily<UUIDType>("StandardUUIDType");
keyspace.TryCreateColumnFamily(new CassandraColumnFamilySchema {
+ FamilyName = "StandardDecimalType",
+ ColumnNameType = CassandraType.DecimalType
+ });
+ keyspace.TryCreateColumnFamily(new CassandraColumnFamilySchema {
FamilyName = "StandardCompositeType",
ColumnNameType = CassandraType.CompositeType(new[] { CassandraType.AsciiType, CassandraType.DoubleType })
});
View
2 test/FluentCassandra.Tests/FluentCassandra.Tests.csproj
@@ -76,6 +76,7 @@
<Compile Include="TypesToDatabase\AsciiTypeTest.cs" />
<Compile Include="TypesToDatabase\BytesTypeTest.cs" />
<Compile Include="TypesToDatabase\CompositeTypeTest.cs" />
+ <Compile Include="TypesToDatabase\DecimalTypeTest.cs" />
<Compile Include="TypesToDatabase\DynamicCompositeTypeTest.cs" />
<Compile Include="TypesToDatabase\TimeUUIDTypeTest.cs" />
<Compile Include="TypesToDatabase\LexicalUUIDTypeTest.cs" />
@@ -84,6 +85,7 @@
<Compile Include="TypesToDatabase\UTF8TypeTest.cs" />
<Compile Include="Types\CompositeTypeTest.cs" />
<Compile Include="Types\CassandraTypeTest.cs" />
+ <Compile Include="Types\DecimalTypeTest.cs" />
<Compile Include="Types\DynamicCompositeTypeTest.cs" />
<Compile Include="Types\IntegerTypeTest.cs" />
<Compile Include="CassandraDatabaseSetup.cs" />
View
110 test/FluentCassandra.Tests/Types/DecimalTypeTest.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using Xunit;
+
+namespace FluentCassandra.Types
+{
+ public class DecimalTypeTest
+ {
+ private readonly BigDecimal bigDecimal = 100002334.4563D;
+ private readonly byte[] dotNetByteOrder = new byte[] { 179, 69, 9, 214, 232, 0, 4, 0, 0, 0 };
+ private readonly byte[] javaByteOrder = new byte[] { 0, 0, 0, 4, 0, 232, 214, 9, 69, 179 };
+
+ [Fact]
+ public void CassandraType_Cast()
+ {
+ // arrange
+ BigDecimal expected = bigDecimal;
+ DecimalType actualType = expected;
+
+ // act
+ CassandraObject actual = actualType;
+
+ // assert
+ Assert.Equal(expected, (BigDecimal)actual);
+ }
+
+ [Fact]
+ public void Implicit_ByteArray_Cast()
+ {
+ // arrange
+ byte[] expected = dotNetByteOrder;
+
+ // act
+ DecimalType actualType = expected;
+ byte[] actual = actualType;
+
+ // assert
+ Assert.True(expected.SequenceEqual(actual));
+ }
+
+ [Fact]
+ public void Implicit_BigDecimal_Cast()
+ {
+ // arrange
+ BigDecimal expected = bigDecimal;
+
+ // act
+ DecimalType actual = expected;
+
+ // assert
+ Assert.Equal(expected, (BigDecimal)actual);
+ }
+
+ [Fact]
+ public void Operator_EqualTo()
+ {
+ // arrange
+ var value = bigDecimal;
+ DecimalType type = value;
+
+ // act
+ bool actual = type.Equals(value);
+
+ // assert
+ Assert.True(actual);
+ }
+
+ [Fact]
+ public void Operator_NotEqualTo()
+ {
+ // arrange
+ var value = bigDecimal;
+ DecimalType type = value;
+
+ // act
+ bool actual = !type.Equals(value);
+
+ // assert
+ Assert.False(actual);
+ }
+
+ [Fact]
+ public void BigDecimal_To_JavaBytes()
+ {
+ // arrange
+
+ // act
+ DecimalType actual = bigDecimal;
+
+ // assert
+ Assert.True(actual.ToBigEndian().SequenceEqual(javaByteOrder));
+ }
+
+ [Fact]
+ public void JavaBytes_To_BigDecimal()
+ {
+ // arrange
+
+ // act
+ DecimalType actual = new DecimalType();
+ actual.SetValueFromBigEndian(javaByteOrder);
+
+ // assert
+ Assert.Equal(bigDecimal, (BigDecimal)actual);
+ }
+ }
+}
View
42 test/FluentCassandra.Tests/TypesToDatabase/DecimalTypeTest.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Numerics;
+using Xunit;
+using FluentCassandra.Types;
+
+namespace FluentCassandra.TypesToDatabase
+{
+
+ public class DecimalTypeTest : IUseFixture<CassandraDatabaseSetupFixture>, IDisposable
+ {
+ private CassandraContext _db;
+
+ public void SetFixture(CassandraDatabaseSetupFixture data)
+ {
+ var setup = data.DatabaseSetup();
+ _db = setup.DB;
+ }
+
+ public void Dispose()
+ {
+ _db.Dispose();
+ }
+
+ public const string FamilyName = "StandardDecimalType";
+ public const string TestKey = "Test1";
+
+ [Fact]
+ public void Save_BigDecimal()
+ {
+ // arrange
+ var family = _db.GetColumnFamily(FamilyName);
+ BigDecimal expected = 100002334.4563D;
+
+ // act
+ family.InsertColumn(TestKey, expected, Math.PI);
+ var actual = family.GetColumn(TestKey, expected);
+
+ // assert
+ Assert.Equal(expected, (BigDecimal)actual.ColumnName);
+ }
+ }
+}

0 comments on commit d05b40e

Please sign in to comment.
Something went wrong with that request. Please try again.