Permalink
Browse files

update TimeUUID to get back the DateTime from the UUID that is generated

  • Loading branch information...
1 parent d18cdbc commit acbb5c34c3eedd95015f6862207b9eba7b71e1b6 @nberardi nberardi committed May 25, 2010
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6CAB5C48-25C9-4F1D-AEAA-DD1577FCCCFB}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>FluentCassandra.Contrib</RootNamespace>
+ <AssemblyName>FluentCassandra.Contrib</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SessionStateProvider.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\FluentCassandra\FluentCassandra.csproj">
+ <Project>{EAA32600-3C2A-4B34-B9B2-5764F280FCE3}</Project>
+ <Name>FluentCassandra</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{323A8829-7B3F-4C41-9FCD-B8B55B6EA8C7}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>FluentCassandra.Contrib.Test</RootNamespace>
+ <AssemblyName>FluentCassandra.Test.Contrib</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
@@ -36,5 +36,33 @@ public void SanityType1Check()
// assert
Assert.AreNotEqual(expected, actual);
}
+
+ [TestMethod]
+ public void GetDateTime()
+ {
+ // arrange
+ var expected = new DateTime(1980, 3, 14, 12, 23, 42, 112);
+ var guid = GuidGenerator.GenerateTimeBasedGuid(expected);
+
+ // act
+ var actual = GuidGenerator.GetDateTime(guid);
+
+ // assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void GetDateTimeOffset()
+ {
+ // arrange
+ var expected = new DateTimeOffset(1980, 3, 14, 12, 23, 42, 112, TimeSpan.Zero);
+ var guid = GuidGenerator.GenerateTimeBasedGuid(expected);
+
+ // act
+ var actual = GuidGenerator.GetDateTimeOffset(guid);
+
+ // assert
+ Assert.AreEqual(expected, actual);
+ }
}
}
@@ -18,69 +18,10 @@ public CassandraColumnFamily(CassandraContext context, CassandraKeyspace keyspac
: base(context, keyspace, connection, columnFamily) { }
public Type CompareWithType { get { return typeof(CompareWith); } }
- }
-}
-
- /*
- private ITypeGetConfiguration<T> _config;
- /// <summary>
- ///
- /// </summary>
- /// <param name="keyspace"></param>
- /// <param name="connection"></param>
- public CassandraColumnFamily(CassandraContext context, CassandraKeyspace keyspace, IConnection connection)
- : base(context, keyspace, connection, CassandraConfiguration.GetMapFor<T>().ColumnFamily)
+ public FluentColumnFamily<CompareWith> CreateFluentFamily(string key)
{
- _config = CassandraConfiguration.GetMapFor<T>();
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="obj"></param>
- /// <returns></returns>
- public FluentColumnFamily PrepareColumnFamily(T obj)
- {
- FluentColumnFamily record = new FluentColumnFamily(
- _config.KeyMap.KeyAccessor(obj),
- _config.ColumnFamily
- );
-
- foreach (var col in _config.PropertyMap)
- {
- var fcol = new FluentColumn {
- Name = col.Alias,
- };
- fcol.SetValue(col.PropertyAccessor(obj));
- record.Columns.Add(fcol);
- }
-
- return record;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="exp"></param>
- /// <returns></returns>
- private string GetName(Expression exp)
- {
- switch (exp.NodeType)
- {
- case ExpressionType.MemberAccess:
- return ((MemberExpression)exp).Member.Name;
-
- case ExpressionType.Convert:
- case ExpressionType.Quote:
- return GetName(((UnaryExpression)exp).Operand);
-
- case ExpressionType.Lambda:
- return GetName(((LambdaExpression)exp).Body);
-
- default:
- return null;
- }
+ return new FluentColumnFamily<CompareWith>(key, FamilyName);
}
}
-}*/
+}
@@ -14,5 +14,11 @@ public CassandraSuperColumnFamily(CassandraContext context, CassandraKeyspace ke
: base(context, keyspace, connection, columnFamily) { }
public Type CompareWithType { get { return typeof(CompareWith); } }
+ public Type CompareSubcolumnWithType { get { return typeof(CompareSubcolumnWith); } }
+
+ public FluentSuperColumnFamily<CompareWith, CompareSubcolumnWith> CreateFluentFamily(string key)
+ {
+ return new FluentSuperColumnFamily<CompareWith, CompareSubcolumnWith>(key, FamilyName);
+ }
}
}
@@ -55,16 +55,48 @@ public static GuidVersion GetVersion(this Guid guid)
return (GuidVersion)((bytes[VersionByte] & 0xFF) >> VersionByteShift);
}
+ public static DateTime GetDateTime(Guid guid)
+ {
+ byte[] bytes = guid.ToByteArray();
+
+ // reverse the version
+ bytes[VersionByte] &= (byte)VersionByteMask;
+ bytes[VersionByte] |= (byte)((byte)GuidVersion.TimeBased >> VersionByteShift);
+
+ byte[] timestampBytes = new byte[8];
+ Array.Copy(bytes, TimestampByte, timestampBytes, 0, 8);
+
+ long timestamp = BitConverter.ToInt64(timestampBytes, 0);
+ long ticks = timestamp + GregorianCalendarStart.Ticks;
+
+ return new DateTime(ticks);
+ }
+
+ public static DateTimeOffset GetDateTimeOffset(Guid guid)
+ {
+ return new DateTimeOffset(GetDateTime(guid), TimeSpan.Zero);
+ }
+
public static Guid GenerateTimeBasedGuid()
{
return GenerateTimeBasedGuid(DateTime.UtcNow, RandomNode);
}
+ public static Guid GenerateTimeBasedGuid(DateTimeOffset dateTime)
+ {
+ return GenerateTimeBasedGuid(dateTime, RandomNode);
+ }
+
public static Guid GenerateTimeBasedGuid(DateTime dateTime)
{
return GenerateTimeBasedGuid(dateTime, RandomNode);
}
+ public static Guid GenerateTimeBasedGuid(DateTimeOffset dateTime, byte[] node)
+ {
+ return GenerateTimeBasedGuid(dateTime.UtcDateTime, node);
+ }
+
public static Guid GenerateTimeBasedGuid(DateTime dateTime, byte[] node)
{
long ticks = dateTime.Ticks - GregorianCalendarStart.Ticks;
@@ -74,13 +106,13 @@ public static Guid GenerateTimeBasedGuid(DateTime dateTime, byte[] node)
byte[] timestamp = BitConverter.GetBytes(ticks);
// copy node
- Array.Copy(node, 0, guid, NodeByte, node.Length);
+ Array.Copy(node, 0, guid, NodeByte, Math.Min(6, node.Length));
// copy clock sequence
- Array.Copy(clockSequenceBytes, 0, guid, GuidClockSequenceByte, clockSequenceBytes.Length);
+ Array.Copy(clockSequenceBytes, 0, guid, GuidClockSequenceByte, Math.Min(2, clockSequenceBytes.Length));
// copy timestamp
- Array.Copy(timestamp, 0, guid, TimestampByte, timestamp.Length);
+ Array.Copy(timestamp, 0, guid, TimestampByte, Math.Min(8, timestamp.Length));
// set the variant
guid[VariantByte] &= (byte)VariantByteMask;
@@ -77,6 +77,20 @@ public override int GetHashCode()
return type._value;
}
+ public static implicit operator TimeUUIDType(DateTime o)
+ {
+ return new TimeUUIDType {
+ _value = GuidGenerator.GenerateTimeBasedGuid(o)
+ };
+ }
+
+ public static implicit operator TimeUUIDType(DateTimeOffset o)
+ {
+ return new TimeUUIDType {
+ _value = GuidGenerator.GenerateTimeBasedGuid(o)
+ };
+ }
+
public static implicit operator TimeUUIDType(Guid o)
{
return new TimeUUIDType {
@@ -10,12 +10,12 @@ internal class TimeUUIDTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
- return sourceType == typeof(byte[]) || sourceType == typeof(Guid);
+ return sourceType == typeof(byte[]) || sourceType == typeof(Guid) || sourceType == typeof(DateTime) || sourceType == typeof(DateTimeOffset);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
- return destinationType == typeof(byte[]) || destinationType == typeof(Guid);
+ return destinationType == typeof(byte[]) || destinationType == typeof(Guid) || destinationType == typeof(DateTime) || destinationType == typeof(DateTimeOffset);
}
private void ReverseLowFieldTimestamp(byte[] guid)
@@ -35,6 +35,12 @@ private void ReverseHighFieldTimestamp(byte[] guid)
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
+ if (value is DateTime)
+ return GuidGenerator.GenerateTimeBasedGuid((DateTime)value);
+
+ if (value is DateTimeOffset)
+ return GuidGenerator.GenerateTimeBasedGuid((DateTimeOffset)value);
+
if (value is byte[] && ((byte[])value).Length == 16)
{
var bytes = (byte[])value;
@@ -55,17 +61,25 @@ public override object ConvertTo(ITypeDescriptorContext context, System.Globaliz
if (!(value is Guid))
return null;
+ Guid guid = ((Guid)value);
+
+ if (destinationType == typeof(DateTime))
+ return GuidGenerator.GetDateTime(guid);
+
+ if (destinationType == typeof(DateTimeOffset))
+ return GuidGenerator.GetDateTimeOffset(guid);
+
if (destinationType == typeof(byte[]))
{
- var bytes = ((Guid)value).ToByteArray();
+ var bytes = guid.ToByteArray();
ReverseLowFieldTimestamp(bytes);
ReverseMiddleFieldTimestamp(bytes);
ReverseHighFieldTimestamp(bytes);
return bytes;
}
if (destinationType == typeof(Guid))
- return (Guid)value;
+ return guid;
return null;
}

0 comments on commit acbb5c3

Please sign in to comment.