Skip to content
This repository has been archived by the owner on May 25, 2021. It is now read-only.

Commit

Permalink
CompositeType and DynamicCompositeType are now supported
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Berardi committed Feb 16, 2012
1 parent 732173d commit 9441ac5
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 56 deletions.
143 changes: 123 additions & 20 deletions src/Types/CassandraType.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Numerics;
using System.Collections.Generic;
using System.Text;

namespace FluentCassandra.Types
{
Expand All @@ -22,9 +24,15 @@ public sealed class CassandraType
public static readonly CassandraType UUIDType = new CassandraType("org.apache.cassandra.db.marshal.UUIDType");
public static readonly CassandraType ColumnCounterType = new CassandraType("org.apache.cassandra.db.marshal.ColumnCounterType");

private static readonly CassandraType _CompositeType = new CassandraType("org.apache.cassandra.db.marshal.CompositeType");
private static readonly CassandraType _DynamicCompositeType = new CassandraType("org.apache.cassandra.db.marshal.DynamicCompositeType");

private readonly string _dbType;
private Type _type;

private IList<Type> _compositeTypes;
private IDictionary<char, Type> _dynamicCompositeType;

public CassandraType(string type)
{
if (type == null || type.Length == 0)
Expand All @@ -38,12 +46,19 @@ public CassandraObject CreateInstance()
if (_type == null)
Parse();

var type = Activator.CreateInstance(_type) as CassandraObject;
CassandraObject obj;

if (_type == typeof(CompositeType))
obj = Activator.CreateInstance(_type, _compositeTypes) as CassandraObject;
else if (_type == typeof(DynamicCompositeType))
obj = Activator.CreateInstance(_type, _dynamicCompositeType) as CassandraObject;
else
obj = Activator.CreateInstance(_type) as CassandraObject;

if (type == null)
if (obj == null)
return null;

return type;
return obj;
}

public string DatabaseType { get { return _dbType; } }
Expand All @@ -59,31 +74,119 @@ public Type FluentType
}
}

private void Parse()
private void Parse()
{
int compositeStart = _dbType.IndexOf('(');

// check for composite type
if (compositeStart == -1) {
_type = Parse(_dbType);
return;
}

var part1 = _dbType.Substring(0, compositeStart);
var part2 = _dbType.Substring(compositeStart);

_type = Parse(part1);

if (_type == typeof(CompositeType))
{
ParseCompositeType(part2);
}
else if (_type == typeof(DynamicCompositeType))
{
ParseDynamicCompositeType(part2);
}
else
{
throw new CassandraException("Type '" + _dbType + "' not found.");
}
}

public void ParseCompositeType(string part)
{
part = part.Trim('(', ')');
var parts = part.Split(',');

_compositeTypes = new List<Type>();
foreach (var p in parts)
_compositeTypes.Add(Parse(p));
}

public void ParseDynamicCompositeType(string part)
{
part = part.Trim('(', ')');
var parts = part.Split(',');

_dynamicCompositeType = new Dictionary<char, Type>();
foreach (var p in parts)
{
char alias = p[0];

if (alias < 33 || alias > 127)
throw new CassandraException("An alias should be a single character in [0..9a..bA..B-+._&]");

if (p[1] != '=' || p[2] != '>')
throw new CassandraException("Expecting operator '=>' after the alias");

string type = p.Substring(3);
_dynamicCompositeType.Add(alias, Parse(type));
}
}

private Type Parse(string dbType)
{
switch (_dbType.Substring(_dbType.LastIndexOf('.') + 1).ToLower())
Type type;

switch (dbType.Substring(dbType.LastIndexOf('.') + 1).ToLower())
{
case "asciitype": _type = typeof(AsciiType); break;
case "booleantype": _type = typeof(BooleanType); break;
case "bytestype": _type = typeof(BytesType); break;
case "datetype": _type = typeof(DateType); break;
case "decimaltype": _type = typeof(DecimalType); break;
case "doubletype": _type = typeof(DoubleType); break;
case "floattype": _type = typeof(FloatType); break;
case "int32type": _type = typeof(Int32Type); break;
case "integertype": _type = typeof(IntegerType); break;
case "lexicaluuidtype": _type = typeof(LexicalUUIDType); break;
case "longtype": _type = typeof(LongType); break;
case "timeuuidtype": _type = typeof(TimeUUIDType); break;
case "utf8type": _type = typeof(UTF8Type); break;
case "uuidtype": _type = typeof(UUIDType); break;
case "asciitype": type = typeof(AsciiType); break;
case "booleantype": type = typeof(BooleanType); break;
case "bytestype": type = typeof(BytesType); break;
case "datetype": type = typeof(DateType); break;
case "decimaltype": type = typeof(DecimalType); break;
case "doubletype": type = typeof(DoubleType); break;
case "floattype": type = typeof(FloatType); break;
case "int32type": type = typeof(Int32Type); break;
case "integertype": type = typeof(IntegerType); break;
case "lexicaluuidtype": type = typeof(LexicalUUIDType); break;
case "longtype": type = typeof(LongType); break;
case "timeuuidtype": type = typeof(TimeUUIDType); break;
case "utf8type": type = typeof(UTF8Type); break;
case "uuidtype": type = typeof(UUIDType); break;
case "compositetype": type = typeof(CompositeType); break;
case "dynamiccompositetype": type = typeof(DynamicCompositeType); break;
default: throw new CassandraException("Type '" + _dbType + "' not found.");
}

return type;
}

public override string ToString()
{
return FluentType.Name;
return _dbType;
}

public static CassandraType CompositeType(IEnumerable<CassandraType> hints)
{
var sb = new StringBuilder();
sb.Append(_CompositeType);
sb.Append("(");
sb.Append(String.Join(",", hints));
sb.Append(")");

return new CassandraType(sb.ToString());
}

public static CassandraType DynamicCompositeType(IDictionary<char, CassandraType> aliases)
{
var sb = new StringBuilder();
sb.Append(_DynamicCompositeType);
sb.Append("(");
sb.Append(String.Join(",", aliases.Select(x => x.Key + "=>" + x.Value)));
sb.Append(")");

return new CassandraType(sb.ToString());
}

public static CassandraType GetCassandraType(Type sourceType)
Expand Down
18 changes: 12 additions & 6 deletions src/Types/CompositeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ public static CompositeType Create(params CassandraObject[] types)

public CompositeType()
{
ComponentTypeHints = new List<Type>();
ComponentTypeHints = new List<CassandraType>();
_value = new List<CassandraObject>();
}

public CompositeType(IEnumerable<CassandraType> hints)
{
ComponentTypeHints = new List<CassandraType>(hints);
_value = new List<CassandraObject>();
}

Expand All @@ -73,7 +79,7 @@ protected override object GetValueInternal(Type type)
public override void SetValue(object obj)
{
if (obj != null && obj.GetType().GetInterfaces().Contains(typeof(IEnumerable<CassandraObject>)))
ComponentTypeHints = ((IEnumerable<CassandraObject>)obj).Select(t => t.GetType()).ToList();
ComponentTypeHints = ((IEnumerable<CassandraObject>)obj).Select(t => new CassandraType(t.GetType().Name)).ToList();

_value = Converter.ConvertFrom(obj);
}
Expand Down Expand Up @@ -102,7 +108,7 @@ public override string ToString()

protected override object GetRawValue() { return _value; }

public List<Type> ComponentTypeHints { get; set; }
public List<CassandraType> ComponentTypeHints { get; set; }

private List<CassandraObject> _value;

Expand Down Expand Up @@ -152,7 +158,7 @@ public static implicit operator CompositeType(DynamicCompositeType type)

return new CompositeType {
_value = value,
ComponentTypeHints = value.Select(t => t.GetType()).ToList()
ComponentTypeHints = value.Select(t => new CassandraType(t.GetType().Name)).ToList()
};
}

Expand All @@ -167,7 +173,7 @@ public static implicit operator CompositeType(CassandraObject[] s)

return new CompositeType {
_value = value,
ComponentTypeHints = value.Select(t => t.GetType()).ToList()
ComponentTypeHints = value.Select(t => new CassandraType(t.GetType().Name)).ToList()
};
}

Expand All @@ -177,7 +183,7 @@ public static implicit operator CompositeType(List<CassandraObject> s)

return new CompositeType {
_value = value,
ComponentTypeHints = value.Select(t => t.GetType()).ToList()
ComponentTypeHints = value.Select(t => new CassandraType(t.GetType().Name)).ToList()
};
}

Expand Down
6 changes: 3 additions & 3 deletions src/Types/CompositeTypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ public override List<CassandraObject> FromBigEndian(byte[] value)
return FromBigEndian(value, null);
}

public List<CassandraObject> FromBigEndian(byte[] value, List<Type> hints)
public List<CassandraObject> FromBigEndian(byte[] value, List<CassandraType> hints)
{
var components = new List<CassandraObject>();
var hintIndex = 0;

hints = hints ?? new List<Type>();
hints = hints ?? new List<CassandraType>();

using (var bytes = new MemoryStream(value))
{
Expand All @@ -158,7 +158,7 @@ public List<CassandraObject> FromBigEndian(byte[] value, List<Type> hints)
// value
var length = BitConverter.ToUInt16(ConvertEndian(byteLength), 0);
var buffer = new byte[length];
var typeHint = (hints.Count >= (hintIndex + 1)) ? hints[hintIndex++] : typeof(BytesType);
var typeHint = (hints.Count >= (hintIndex + 1)) ? hints[hintIndex++] : CassandraType.BytesType;
bytes.Read(buffer, 0, length);

var component = CassandraObject.GetTypeFromDatabaseValue(buffer, typeHint);
Expand Down
10 changes: 5 additions & 5 deletions src/Types/CompositeType`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public CompositeType(T1 t1)

public CompositeType()
{
ComponentTypeHints = GetType().GetGenericArguments().ToList();
ComponentTypeHints = GetType().GetGenericArguments().Select(x => new CassandraType(x.Name)).ToList();
}

public T1 Item1 { get { return (T1)GetValue<List<CassandraObject>>()[0]; } }
Expand All @@ -31,7 +31,7 @@ public CompositeType(T1 t1, T2 t2)

public CompositeType()
{
ComponentTypeHints = GetType().GetGenericArguments().ToList();
ComponentTypeHints = GetType().GetGenericArguments().Select(x => new CassandraType(x.Name)).ToList();
}

public T1 Item1 { get { return (T1)GetValue<List<CassandraObject>>()[0]; } }
Expand All @@ -50,7 +50,7 @@ public CompositeType(T1 t1, T2 t2, T3 t3)

public CompositeType()
{
ComponentTypeHints = GetType().GetGenericArguments().ToList();
ComponentTypeHints = GetType().GetGenericArguments().Select(x => new CassandraType(x.Name)).ToList();
}

public T1 Item1 { get { return (T1)GetValue<List<CassandraObject>>()[0]; } }
Expand All @@ -71,7 +71,7 @@ public CompositeType(T1 t1, T2 t2, T3 t3, T4 t4)

public CompositeType()
{
ComponentTypeHints = GetType().GetGenericArguments().ToList();
ComponentTypeHints = GetType().GetGenericArguments().Select(x => new CassandraType(x.Name)).ToList();
}

public T1 Item1 { get { return (T1)GetValue<List<CassandraObject>>()[0]; } }
Expand All @@ -94,7 +94,7 @@ public CompositeType(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)

public CompositeType()
{
ComponentTypeHints = GetType().GetGenericArguments().ToList();
ComponentTypeHints = GetType().GetGenericArguments().Select(x => new CassandraType(x.Name)).ToList();
}

public T1 Item1 { get { return (T1)GetValue<List<CassandraObject>>()[0]; } }
Expand Down
32 changes: 16 additions & 16 deletions src/Types/DynamicCompositeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@ public class DynamicCompositeType : CassandraObject, IList<CassandraObject>
private readonly DynamicCompositeTypeConverter Converter;

public DynamicCompositeType()
: this(new Dictionary<char, Type> {
{ 'b', typeof(BooleanType) },
{ 't', typeof(DateType) },
{ 'm', typeof(DecimalType) },
{ 'f', typeof(FloatType) },
{ 'd', typeof(DoubleType) },
{ 'i', typeof(Int32Type) },
{ 'l', typeof(LongType) },
{ 'z', typeof(IntegerType) },
{ 'a', typeof(AsciiType) },
{ 's', typeof(UTF8Type) },
{ 'x', typeof(BytesType) },
{ 'u', typeof(UUIDType) },
{ '1', typeof(TimeUUIDType) },
{ '2', typeof(LexicalUUIDType) }
: this(new Dictionary<char, CassandraType> {
{ 'b', CassandraType.BooleanType },
{ 't', CassandraType.DateType },
{ 'm', CassandraType.DecimalType },
{ 'f', CassandraType.FloatType },
{ 'd', CassandraType.DoubleType },
{ 'i', CassandraType.Int32Type },
{ 'l', CassandraType.LongType },
{ 'z', CassandraType.IntegerType },
{ 'a', CassandraType.AsciiType },
{ 's', CassandraType.UTF8Type },
{ 'x', CassandraType.BytesType },
{ 'u', CassandraType.UUIDType },
{ '1', CassandraType.TimeUUIDType },
{ '2', CassandraType.LexicalUUIDType }
}) { }

public DynamicCompositeType(IDictionary<char, Type> aliases)
public DynamicCompositeType(IDictionary<char, CassandraType> aliases)
{
Converter = new DynamicCompositeTypeConverter(aliases);
_value = new List<CassandraObject>();
Expand Down
6 changes: 3 additions & 3 deletions src/Types/DynamicCompositeTypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ namespace FluentCassandra.Types
{
internal class DynamicCompositeTypeConverter : CassandraObjectConverter<List<CassandraObject>>
{
private readonly IDictionary<char, Type> _aliases;
private readonly IDictionary<char, CassandraType> _aliases;

public DynamicCompositeTypeConverter(IDictionary<char, Type> aliases)
public DynamicCompositeTypeConverter(IDictionary<char, CassandraType> aliases)
{
this._aliases = aliases;
}
Expand Down Expand Up @@ -88,7 +88,7 @@ public override object ConvertToInternal(List<CassandraObject> value, Type desti

// comparator part
bytes.WriteByte((byte)1);
bytes.WriteByte((byte)_aliases.FirstOrDefault(x => x.Value == c.GetType()).Key);
bytes.WriteByte((byte)_aliases.FirstOrDefault(x => x.Value.FluentType == c.GetType()).Key);

// value length
bytes.Write(BitConverter.GetBytes(length), 0, 2);
Expand Down
Loading

0 comments on commit 9441ac5

Please sign in to comment.