mardi 29 avril 2014

Cassandra timeuuid dans le pilote Datastax c# - Stack Overflow


What C# type is equivalent to the timeuuid in the Datastax Cassandra C# driver?


I am writing a simple user tracking service and want to access the most latest user history. I am trying to create a table equivalent to this create statement:


CREATE TABLE IF NOT EXISTS user_history (
user_id text,
event_type text,
create_date timeuuid,
item_id text,
PRIMARY KEY ((user_id, event_type), create_date)
);

I have made the following class:


[AllowFiltering]
[Table("user_history")]
public class UserHistory
{
[PartitionKey(1)]
[Column("user_id")]
public string UserID;

[PartitionKey(2)]
[Column("event_type")]
public string EventType;

[ClusteringKey(1)]
[Column("create_date")]
public DateTime CreateDate { get; set; }

[Column("item_id")]
public string ItemID;
}

And I am using this statement to create the table in Cassandra:


var table = Session.GetTable<UserHistory>();
table.CreateIfNotExists();

But this gives me the following table:


CREATE TABLE user_history (
user_id text,
event_type text,
create_date timestamp,
item_id text,
PRIMARY KEY ((user_id, event_type), create_date)
)

As you can see, the type of create_date is timestamp instead of timeuuid.


I have tried Guid instead of DateTime, but that gives me an uuid when I am calling .CreateIfNotExists().


Should I use Guid instead of DateTime for the CreateDate and create the table explicit using raw CQL3? I guess this will allow me to read and write timeuuid from/to Cassandra (using the GuidGenerator found in the FluentCassandra project)?! (Recall: I am using the Datastax driver)




Timeuuid is basically a guid and so you should use a guid, the following code is taken from here: creating-a-time-uuid-guid-in-net and is part of the FluentCassandra project


"Below is all the code you need to generate a Time UUID or Time-Based Guid object in .NET. "


public static Guid GenerateTimeBasedGuid(DateTime dateTime)  
{
long ticks = dateTime.Ticks - GregorianCalendarStart.Ticks;

byte[] guid = new byte[ByteArraySize];
byte[] clockSequenceBytes = BitConverter.GetBytes(Convert.ToInt16(Environment.TickCount % Int16.MaxValue));
byte[] timestamp = BitConverter.GetBytes(ticks);

// copy node
Array.Copy(Node, 0, guid, NodeByte, Node.Length);

// copy clock sequence
Array.Copy(clockSequenceBytes, 0, guid, GuidClockSequenceByte, clockSequenceBytes.Length);

// copy timestamp
Array.Copy(timestamp, 0, guid, 0, timestamp.Length);

// set the variant
guid[VariantByte] &= (byte)VariantByteMask;
guid[VariantByte] |= (byte)VariantByteShift;

// set the version
guid[VersionByte] &= (byte)VersionByteMask;
guid[VersionByte] |= (byte)((int)GuidVersion.TimeBased << VersionByteShift);

return new Guid(guid);
}


What C# type is equivalent to the timeuuid in the Datastax Cassandra C# driver?


I am writing a simple user tracking service and want to access the most latest user history. I am trying to create a table equivalent to this create statement:


CREATE TABLE IF NOT EXISTS user_history (
user_id text,
event_type text,
create_date timeuuid,
item_id text,
PRIMARY KEY ((user_id, event_type), create_date)
);

I have made the following class:


[AllowFiltering]
[Table("user_history")]
public class UserHistory
{
[PartitionKey(1)]
[Column("user_id")]
public string UserID;

[PartitionKey(2)]
[Column("event_type")]
public string EventType;

[ClusteringKey(1)]
[Column("create_date")]
public DateTime CreateDate { get; set; }

[Column("item_id")]
public string ItemID;
}

And I am using this statement to create the table in Cassandra:


var table = Session.GetTable<UserHistory>();
table.CreateIfNotExists();

But this gives me the following table:


CREATE TABLE user_history (
user_id text,
event_type text,
create_date timestamp,
item_id text,
PRIMARY KEY ((user_id, event_type), create_date)
)

As you can see, the type of create_date is timestamp instead of timeuuid.


I have tried Guid instead of DateTime, but that gives me an uuid when I am calling .CreateIfNotExists().


Should I use Guid instead of DateTime for the CreateDate and create the table explicit using raw CQL3? I guess this will allow me to read and write timeuuid from/to Cassandra (using the GuidGenerator found in the FluentCassandra project)?! (Recall: I am using the Datastax driver)



Timeuuid is basically a guid and so you should use a guid, the following code is taken from here: creating-a-time-uuid-guid-in-net and is part of the FluentCassandra project


"Below is all the code you need to generate a Time UUID or Time-Based Guid object in .NET. "


public static Guid GenerateTimeBasedGuid(DateTime dateTime)  
{
long ticks = dateTime.Ticks - GregorianCalendarStart.Ticks;

byte[] guid = new byte[ByteArraySize];
byte[] clockSequenceBytes = BitConverter.GetBytes(Convert.ToInt16(Environment.TickCount % Int16.MaxValue));
byte[] timestamp = BitConverter.GetBytes(ticks);

// copy node
Array.Copy(Node, 0, guid, NodeByte, Node.Length);

// copy clock sequence
Array.Copy(clockSequenceBytes, 0, guid, GuidClockSequenceByte, clockSequenceBytes.Length);

// copy timestamp
Array.Copy(timestamp, 0, guid, 0, timestamp.Length);

// set the variant
guid[VariantByte] &= (byte)VariantByteMask;
guid[VariantByte] |= (byte)VariantByteShift;

// set the version
guid[VersionByte] &= (byte)VersionByteMask;
guid[VersionByte] |= (byte)((int)GuidVersion.TimeBased << VersionByteShift);

return new Guid(guid);
}

0 commentaires:

Enregistrer un commentaire