private static CqlColumn[] CreateColumns(ICollection <KeyValuePair <string, object> > rowValues) { var columns = new CqlColumn[rowValues.Count]; var index = 0; var serializer = new Serializer(ProtocolVersion.MaxSupported); foreach (var kv in rowValues) { CqlColumn c; if (kv.Value != null) { IColumnInfo typeInfo; var typeCode = serializer.GetCqlType(kv.Value.GetType(), out typeInfo); c = new CqlColumn { Name = kv.Key, TypeCode = typeCode, TypeInfo = typeInfo, Type = kv.Value.GetType(), Index = index }; } else { // Default to type Text c = new CqlColumn { Name = kv.Key, TypeCode = ColumnTypeCode.Text, Type = typeof(string), Index = index }; } columns[index++] = c; } return(columns); }
/// <summary> /// Creates a mapper that flattens a single column's value directly to the "POCO"'s value. (POCO here most likely being a value type/string/etc.) /// </summary> private Func <Row, T> CreateMapperForSingleColumnToPoco <T>(RowSet rows, PocoData pocoData) { ParameterExpression row = Expression.Parameter(CassandraRowType, "row"); CqlColumn dbColumn = rows.Columns[0]; LabelTarget returnTarget = Expression.Label(pocoData.PocoType); // Get an expression for getting the value of the single column as TPoco (and returning it) Expression getColumnValue = Expression.Return(returnTarget, GetExpressionToGetColumnValueFromRow(row, dbColumn, pocoData.PocoType)); // If it is null, try to provide an empty collection for collection types, otherwise do nothing (empty expression) Expression ifIsNull = Expression.Empty(); Expression createEmptyCollection; if (TryGetCreateEmptyCollectionExpression(dbColumn, pocoData.PocoType, out createEmptyCollection)) { ifIsNull = Expression.Return(returnTarget, createEmptyCollection); } // if (row.IsNull(0) == false) // return ... getColumnValue ... // else // return ... empty collection or default(TPoco) ... var methodBody = Expression.Block( Expression.IfThenElse( Expression.IsFalse(Expression.Call(row, IsNullMethod, Expression.Constant(0, IntType))), getColumnValue, ifIsNull), Expression.Label(returnTarget, Expression.Default(pocoData.PocoType))); return(Expression.Lambda <Func <Row, T> >(methodBody, row).Compile()); }
public void Row_TryConvertToType_Should_Convert_Sets() { var setIntTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.Set, TypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Int }, Type = typeof(IEnumerable <int>) }; var values = new[] { new object[] { new [] { 1, 2, 3 }, setIntTypeInfo, typeof(int[]) }, new object[] { new [] { 1, 2, 3 }, setIntTypeInfo, typeof(object), typeof(int[]) }, new object[] { new [] { 1, 2, 3 }, setIntTypeInfo, typeof(IEnumerable <int>), typeof(int[]) }, new object[] { new [] { 1, 2, 3 }, setIntTypeInfo, typeof(HashSet <int>) }, new object[] { new [] { 1, 2, 3 }, setIntTypeInfo, typeof(SortedSet <int>) }, new object[] { new [] { 1, 2, 3 }, setIntTypeInfo, typeof(ISet <int>), typeof(SortedSet <int>) } }; foreach (var item in values) { var value = Row.TryConvertToType(item[0], (CqlColumn)item[1], (Type)item[2]); Assert.AreEqual(item.Length > 3 ? item[3] : item[2], value.GetType()); CollectionAssert.AreEqual((int[])item[0], (IEnumerable <int>)value); } }
/// <summary> /// Tries to set a property or field of the specified object, based on the column description /// </summary> /// <param name="column"> The column. </param> /// <param name="target"> The target. </param> /// <param name="value"> The value. </param> /// <returns> true if the property or field value is set </returns> /// <exception cref="System.ArgumentNullException">column</exception> /// <exception cref="System.ArgumentException">Source is not of the correct type!;target</exception> public bool TrySetValue(CqlColumn column, T target, object value) { Action <T, object> func; if (_keySpaceSet && _tableSet) { if (_writeFuncs.TryGetValue(column.KsTableNameNormalized, out func)) { func(target, value); return(true); } } else if (_tableSet) { if (_writeFuncs.TryGetValue(column.TableNameNormalized, out func)) { func(target, value); return(true); } } else if (_writeFuncs.TryGetValue(column.NameNormalized, out func)) { func(target, value); return(true); } return(false); }
public void MapUDT(CqlColumn col, RowSet R) { try { if (((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeCode.ToString() == "Udt") { var name = ((Cassandra.UdtColumnInfo)((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeInfo).Name; ConnectWithKeyspace(name); int a = ((Cassandra.UdtColumnInfo)((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeInfo).Fields.Count; Dictionary <string, Type> keyvalue = new Dictionary <string, Type>(); Type t = null; for (int k = 0; k < a; k++) { dynamic Fieldname = (((Cassandra.UdtColumnInfo)((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeInfo).Fields[k].Name).ToString(); var Fieldtype = ((Cassandra.UdtColumnInfo)((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeInfo).Fields[k].TypeCode; Type ks = Fieldtype.GetType(); t = TypeConverter(R, Fieldtype.ToString()); keyvalue.Add(Fieldname, t); } string[] stringarray = keyvalue.Keys.ToArray(); Type[] typearray = keyvalue.Values.ToArray(); CreateDynamicClass(t, mUDTName, stringarray, typearray); } } catch (Exception e) { Reporter.ToLog(eLogLevel.ERROR, $"Method - {MethodBase.GetCurrentMethod().Name}, Error - {e.Message}"); } }
/// <summary> /// Creates a rowset. /// The columns are named: col_0, ..., col_n /// The rows values are: row_0_col_0, ..., row_m_col_n /// </summary> private static RowSet CreateStringsRowset(int columnLength, int rowLength, string valueModifier = null) { var columns = new List <CqlColumn>(); var columnIndexes = new Dictionary <string, int>(); for (var i = 0; i < columnLength; i++) { var c = new CqlColumn() { Index = i, Name = "col_" + i, TypeCode = ColumnTypeCode.Text, Type = typeof(string) }; columns.Add(c); columnIndexes.Add(c.Name, c.Index); } var rs = new RowSet(); for (var j = 0; j < rowLength; j++) { rs.AddRow(new Row(columns.Select(c => valueModifier + "row_" + j + "_col_" + c.Index).Cast <object>().ToArray(), columns.ToArray(), columnIndexes)); } return(rs); }
/// <summary> /// Creates a rowset. /// The columns are named: col_0, ..., col_n /// The rows values are: row_0_col_0, ..., row_m_col_n /// </summary> public RowSet CreateStringsRowset(int columnLength, int rowLength, string valueModifier = null) { var columns = new List<CqlColumn>(); var columnIndexes = new Dictionary<string, int>(); for (var i = 0; i < columnLength; i++) { var c = new CqlColumn() { Index = i, Name = "col_" + i, TypeCode = ColumnTypeCode.Text, Type = typeof(string) }; columns.Add(c); columnIndexes.Add(c.Name, c.Index); } var rs = new RowSet(); for (var j = 0; j < rowLength; j++) { var rowValues = new List<byte[]>(); foreach (var c in columns) { var value = valueModifier + "row_" + j + "_col_" + c.Index; rowValues.Add(Encoding.UTF8.GetBytes(value)); } rs.AddRow(new Row(1, rowValues.ToArray(), columns.ToArray(), columnIndexes)); } return rs; }
public void ListUDT(CqlColumn col, RowSet R) { if (((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeCode.ToString() == "Udt") { var name = ((Cassandra.UdtColumnInfo)((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeInfo).Name; ConnectWithKeyspace(name); int a = ((Cassandra.UdtColumnInfo)((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeInfo).Fields.Count; Dictionary <string, Type> keyvalue = new Dictionary <string, Type>(); Type t = null; for (int k = 0; k < a; k++) { dynamic Fieldname = (((Cassandra.UdtColumnInfo)((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeInfo).Fields[k].Name).ToString(); var Fieldtype = ((Cassandra.UdtColumnInfo)((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeInfo).Fields[k].TypeCode; Type ks = Fieldtype.GetType(); t = TypeConverter(R, Fieldtype.ToString()); keyvalue.Add(Fieldname, t); } string[] stringarray = keyvalue.Keys.ToArray(); Type[] typearray = keyvalue.Values.ToArray(); CreateDynamicClass(t, mUDTName, stringarray, typearray); } }
/// <summary> /// Creates a rowset. /// The columns are named: col_0, ..., col_n /// The rows values are: row_0_col_0, ..., row_m_col_n /// </summary> private static RowSet CreateStringsRowset(int columnLength, int rowLength, string valueModifier = null) { var columns = new List <CqlColumn>(); var columnIndexes = new Dictionary <string, int>(); for (var i = 0; i < columnLength; i++) { var c = new CqlColumn() { Index = i, Name = "col_" + i, TypeCode = ColumnTypeCode.Text, Type = typeof(string) }; columns.Add(c); columnIndexes.Add(c.Name, c.Index); } var rs = new RowSet(); for (var j = 0; j < rowLength; j++) { var rowValues = new List <byte[]>(); foreach (var c in columns) { var value = valueModifier + "row_" + j + "_col_" + c.Index; rowValues.Add(Encoding.UTF8.GetBytes(value)); } rs.AddRow(new Row(1, rowValues.ToArray(), columns.ToArray(), columnIndexes)); } return(rs); }
public void RetriveSet(CqlColumn col, Row r, Type t, int i) { dynamic value = r.GetValue(typeof(object), col.Name); var value1 = r.GetValue(typeof(object), col.Name); myclass = value1; string am = ((Cassandra.SetColumnInfo)col.TypeInfo).KeyTypeCode.ToString(); if (am == "Udt") { int a = ((Cassandra.UdtColumnInfo)((Cassandra.SetColumnInfo)col.TypeInfo).KeyTypeInfo).Fields.Count; Dictionary <string, object> keyvalue = new Dictionary <string, object>(); Type TP = myclass.GetType(); try { for (int k = 0; k < a; k++) { dynamic Fieldname = (((Cassandra.UdtColumnInfo)((Cassandra.SetColumnInfo)col.TypeInfo).KeyTypeInfo).Fields[k].Name).ToString(); try { for (int s = 0; s < a; s++) { var nameOfProperty = Fieldname; var propertyInfo = value[s].GetType().GetProperty(nameOfProperty); var valueUDT = propertyInfo.GetValue(value[s], null); if (k > 0) { Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + nameOfProperty + "." + s.ToString(), valueUDT, i.ToString()); } else { Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + nameOfProperty, valueUDT, i.ToString()); } } } catch (Exception e) { Reporter.ToLog(eLogLevel.ERROR, $"Method - {MethodBase.GetCurrentMethod().Name}, Error - {e.Message}"); } } } catch (Exception e) { Console.WriteLine(e.StackTrace); } } else { // retrieve values of Set without UDTs int m = 0; foreach (object o in value) { Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + m, o.ToString(), i.ToString()); m++; } } }
/// <summary> /// Creates a mapper that flattens a single column's value directly to the "POCO"'s value. (POCO here most likely being a value type/string/etc.) /// </summary> private Func <Row, T> CreateMapperForSingleColumnToPoco <T>(RowSet rows, PocoData pocoData) { ParameterExpression row = Expression.Parameter(CassandraRowType, "row"); CqlColumn dbColumn = rows.Columns[0]; // Get an expression for getting the value of the single column as TPoco (and returning it) Expression getColumnOrDefault = GetExpressionToGetColumnValueFromRow(row, dbColumn, pocoData.PocoType); return(Expression.Lambda <Func <Row, T> >(getColumnOrDefault, row).Compile()); }
public void RetriveMap(CqlColumn col, Row r, Type t, int i) { dynamic value = r.GetValue(typeof(object), col.Name); myclass = value; string IFUDT = ((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeCode.ToString(); if (IFUDT == "Udt") { int a = ((Cassandra.UdtColumnInfo)((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeInfo).Fields.Count; //Dictionary<string, object> keyvalue = new Dictionary<string, object>(); dynamic abc; try { foreach (var item in (dynamic)myclass) { abc = item.Value; for (int k = 0; k < a; k++) { try { dynamic Fieldname = (((Cassandra.UdtColumnInfo)((Cassandra.MapColumnInfo)col.TypeInfo).ValueTypeInfo).Fields[k].Name).ToString(); var nameOfProperty = Fieldname; var propertyInfo = abc.GetType().GetProperty(nameOfProperty); var valueUDT = propertyInfo.GetValue(abc, null); Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + nameOfProperty, valueUDT.ToString(), i.ToString()); } catch (Exception e) { Reporter.ToLog(eLogLevel.ERROR, $"Method - {MethodBase.GetCurrentMethod().Name}, Error - {e.Message}"); } } } } catch (Exception e) { Reporter.ToLog(eLogLevel.ERROR, $"Method - {MethodBase.GetCurrentMethod().Name}, Error - {e.Message}"); } } else {// to retrieve values without udt int m = 0; foreach (object o in value) { Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + m, o.ToString(), i.ToString()); m++; } } }
public void RetriveList(CqlColumn col, Row r, Type t, int i) { dynamic value = r.GetValue(typeof(object), col.Name); var value1 = r.GetValue(typeof(object), col.Name); myclass = value1; if (((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeCode.ToString() == "Udt") { int a = ((Cassandra.UdtColumnInfo)((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeInfo).Fields.Count; for (int k = 0; k < a; k++) { dynamic Fieldname = (((Cassandra.UdtColumnInfo)((Cassandra.ListColumnInfo)col.TypeInfo).ValueTypeInfo).Fields[k].Name).ToString(); try { for (int s = 0; s < a; s++) { var nameOfProperty = Fieldname; var propertyInfo = value[s].GetType().GetProperty(nameOfProperty); var valueUDT = propertyInfo.GetValue(value[s], null); if (k > 0) { Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + nameOfProperty + "." + s.ToString(), valueUDT, i.ToString()); } else { Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + nameOfProperty, valueUDT, i.ToString()); } } } catch (Exception e) { Reporter.ToLog(eLogLevel.ERROR, $"Method - {MethodBase.GetCurrentMethod().Name}, Error - {e.Message}", e); } } } else { // retrieve list values without UDT int m = 0; foreach (object o in value) { Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + m, o.ToString(), i.ToString()); m++; } } }
/// <summary> /// Tries to get a value from the source, based on the column description /// </summary> /// <param name="column"> The column. </param> /// <param name="source"> The source. </param> /// <param name="value"> The value. </param> /// <returns> true, if the value could be distilled from the source </returns> /// <exception cref="System.ArgumentNullException">column</exception> /// <exception cref="System.ArgumentException">Source is not of the correct type!;source</exception> public bool TryGetValue(CqlColumn column, T source, out object value) { if (column == null) { throw new ArgumentNullException("column"); } // ReSharper disable CompareNonConstrainedGenericWithNull if (source == null) { // ReSharper restore CompareNonConstrainedGenericWithNull throw new ArgumentNullException("source"); } if (source.GetType() != typeof(T)) { throw new ArgumentException("Source is not of the correct type!", "source"); } Func <T, object> func; if (_keySpaceSet && _tableSet) { if (_readFuncs.TryGetValue(column.KsTableNameNormalized, out func)) { value = func(source); return(true); } } else if (_tableSet) { if (_readFuncs.TryGetValue(column.TableNameNormalized, out func)) { value = func(source); return(true); } } else if (_readFuncs.TryGetValue(column.NameNormalized, out func)) { value = func(source); return(true); } value = null; return(false); }
/// <summary> /// Performs a lightweight validation to determine if the source type and target type matches. /// It isn't more strict to support miscellaneous uses of the driver, like direct inputs of blobs and all that. (backward compatibility) /// </summary> public bool IsAssignableFrom(CqlColumn column, object value) { if (value == null || value is byte[]) { return(true); } var type = value.GetType(); ITypeSerializer typeSerializer; if (_primitiveSerializers.TryGetValue(type, out typeSerializer)) { var cqlType = typeSerializer.CqlType; //Its a single type, if the types match -> go ahead if (cqlType == column.TypeCode) { return(true); } //Only int32 and blobs are valid cql ints if (column.TypeCode == ColumnTypeCode.Int) { return(false); } //Only double, longs and blobs are valid cql double if (column.TypeCode == ColumnTypeCode.Double && !(value is long)) { return(false); } //The rest of the single values are not evaluated return(true); } if (column.TypeCode == ColumnTypeCode.List || column.TypeCode == ColumnTypeCode.Set) { return(value is IEnumerable); } if (column.TypeCode == ColumnTypeCode.Map) { return(value is IDictionary); } if (column.TypeCode == ColumnTypeCode.Tuple) { return(value is IStructuralComparable); } return(true); }
public void Row_TryConvertToType_Should_Convert_Nested_Collections() { var setTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.Set, TypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Set, KeyTypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Int } } }; var listTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.List, TypeInfo = new ListColumnInfo { ValueTypeCode = ColumnTypeCode.Set, ValueTypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Timeuuid } } }; var values = new[] { Tuple.Create((IEnumerable) new [] { new Guid[] { TimeUuid.NewId() } }, listTypeInfo, typeof(TimeUuid[][])), Tuple.Create((IEnumerable) new [] { new [] { Guid.NewGuid() } }, listTypeInfo, typeof(Guid[][])), Tuple.Create((IEnumerable) new [] { new Guid[] { TimeUuid.NewId() } }, listTypeInfo, typeof(SortedSet <TimeUuid>[])), Tuple.Create((IEnumerable) new [] { new [] { Guid.NewGuid() } }, listTypeInfo, typeof(HashSet <Guid>[])), Tuple.Create((IEnumerable) new [] { new [] { 314 } }, setTypeInfo, typeof(HashSet <int>[])), Tuple.Create((IEnumerable) new [] { new [] { 213 } }, setTypeInfo, typeof(int[][])), Tuple.Create((IEnumerable) new [] { new [] { 111 } }, setTypeInfo, typeof(SortedSet <SortedSet <int> >)) }; foreach (var item in values) { var value = Row.TryConvertToType(item.Item1, item.Item2, item.Item3); Assert.True(item.Item3.GetTypeInfo().IsInstanceOfType(value), "{0} is not assignable from {1}", item.Item3, value.GetType()); Assert.AreEqual(TestHelper.FirstString(item.Item1), TestHelper.FirstString((IEnumerable)value)); } }
public void Row_TryConvertToType_Should_Convert_Timestamps() { var timestampTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.Timestamp }; var values = new[] { //column desc, value, type and expected type new object[] { DateTimeOffset.Now, timestampTypeInfo, typeof(DateTime) }, new object[] { DateTimeOffset.Now, timestampTypeInfo, typeof(DateTimeOffset) }, new object[] { DateTimeOffset.Now, timestampTypeInfo, typeof(object), typeof(DateTimeOffset) }, new object[] { DateTimeOffset.Now, timestampTypeInfo, typeof(IConvertible), typeof(DateTime) } }; foreach (var item in values) { var value = Row.TryConvertToType(item[0], (CqlColumn)item[1], (Type)item[2]); Assert.AreEqual(item.Length > 3 ? item[3] : item[2], value.GetType()); } }
public void Row_TryConvertToType_Should_Convert_Uuid_Collections() { var setTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.Set, TypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Timeuuid } }; var listTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.List, TypeInfo = new ListColumnInfo { ValueTypeCode = ColumnTypeCode.Timeuuid } }; var values = new[] { Tuple.Create(new Guid[] { TimeUuid.NewId() }, setTypeInfo, typeof(TimeUuid[])), Tuple.Create(new Guid[] { TimeUuid.NewId() }, setTypeInfo, typeof(SortedSet <TimeUuid>)), Tuple.Create(new Guid[] { TimeUuid.NewId() }, listTypeInfo, typeof(List <TimeUuid>)), Tuple.Create(new Guid[] { TimeUuid.NewId() }, setTypeInfo, typeof(HashSet <TimeUuid>)), Tuple.Create(new Guid[] { TimeUuid.NewId() }, setTypeInfo, typeof(ISet <TimeUuid>)), Tuple.Create(new Guid[] { Guid.NewGuid() }, setTypeInfo, typeof(HashSet <Guid>)), Tuple.Create(new Guid[] { Guid.NewGuid() }, setTypeInfo, typeof(SortedSet <Guid>)), Tuple.Create(new Guid[] { Guid.NewGuid() }, listTypeInfo, typeof(List <Guid>)), Tuple.Create(new Guid[] { Guid.NewGuid() }, listTypeInfo, typeof(Guid[])), Tuple.Create(new Guid[] { Guid.NewGuid() }, listTypeInfo, typeof(IList <Guid>)) }; foreach (var item in values) { var value = Row.TryConvertToType(item.Item1, item.Item2, item.Item3); Assert.True(item.Item3.GetTypeInfo().IsInstanceOfType(value), "{0} is not assignable from {1}", item.Item3, value.GetType()); Assert.AreEqual(item.Item1.First().ToString(), (from object v in (IEnumerable)value select v.ToString()).FirstOrDefault()); } }
public void Row_TryConvertToType_Should_Convert_Timestamp_Collections() { var setTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.Set, TypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Timestamp }, Type = typeof(IEnumerable <DateTimeOffset>) }; var listTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.List, TypeInfo = new ListColumnInfo { ValueTypeCode = ColumnTypeCode.Timestamp } }; var values = new[] { Tuple.Create(new [] { DateTimeOffset.UtcNow }, setTypeInfo, typeof(DateTime[])), Tuple.Create(new [] { DateTimeOffset.UtcNow }, setTypeInfo, typeof(SortedSet <DateTime>)), Tuple.Create(new [] { DateTimeOffset.UtcNow }, listTypeInfo, typeof(List <DateTime>)), Tuple.Create(new [] { DateTimeOffset.UtcNow }, setTypeInfo, typeof(HashSet <DateTime>)), Tuple.Create(new [] { DateTimeOffset.UtcNow }, setTypeInfo, typeof(HashSet <DateTimeOffset>)), Tuple.Create(new [] { DateTimeOffset.UtcNow }, setTypeInfo, typeof(SortedSet <DateTimeOffset>)), Tuple.Create(new [] { DateTimeOffset.UtcNow }, listTypeInfo, typeof(List <DateTimeOffset>)), Tuple.Create(new [] { DateTimeOffset.UtcNow }, listTypeInfo, typeof(DateTimeOffset[])) }; foreach (var item in values) { var value = Row.TryConvertToType(item.Item1, item.Item2, item.Item3); Assert.True(item.Item3.GetTypeInfo().IsInstanceOfType(value), "{0} is not assignable from {1}", item.Item3, value.GetType()); Assert.AreEqual(item.Item1.First().Ticks, (from object v in (IEnumerable)value select(v is DateTime ? ((DateTime)v).Ticks : ((DateTimeOffset)v).Ticks)).FirstOrDefault()); } }
public void Row_TryConvertToType_Should_Convert_Dictionaries() { var mapTypeInfo1 = new CqlColumn { TypeCode = ColumnTypeCode.Map, TypeInfo = new MapColumnInfo { KeyTypeCode = ColumnTypeCode.Timeuuid, ValueTypeCode = ColumnTypeCode.Set, ValueTypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Int } } }; var values = new[] { Tuple.Create( (IDictionary) new SortedDictionary <Guid, IEnumerable <int> > { { Guid.NewGuid(), new[] { 1, 2, 3 } } }, mapTypeInfo1, typeof(SortedDictionary <Guid, IEnumerable <int> >)), Tuple.Create( (IDictionary) new SortedDictionary <Guid, IEnumerable <int> > { { TimeUuid.NewId(), new[] { 1, 2, 3 } } }, mapTypeInfo1, typeof(IDictionary <TimeUuid, int[]>)) }; foreach (var item in values) { var value = Row.TryConvertToType(item.Item1, item.Item2, item.Item3); Assert.True(item.Item3.GetTypeInfo().IsInstanceOfType(value), "{0} is not assignable from {1}", item.Item3, value.GetType()); Assert.AreEqual(TestHelper.FirstString(item.Item1), TestHelper.FirstString((IEnumerable)value)); } }
public void RetriveUDT(CqlColumn col, Row r, Type t, int i) { dynamic value = r.GetValue(typeof(object), col.Name); dynamic val = r.GetValue(t, col.Name); myclass = val; int a = ((Cassandra.UdtColumnInfo)col.TypeInfo).Fields.Count; Dictionary <string, object> keyvalue = new Dictionary <string, object>(); Type TP = myclass.GetType(); for (int k = 0; k < a; k++) { dynamic Fieldname = (((Cassandra.UdtColumnInfo)col.TypeInfo).Fields[k].Name).ToString(); var nameOfProperty = Fieldname; var propertyInfo = value.GetType().GetProperty(nameOfProperty); var valueUDT = propertyInfo.GetValue(value, null); keyvalue.Add(Fieldname, t); Act.AddOrUpdateReturnParamActualWithPath(col.Name + "." + nameOfProperty, valueUDT, i.ToString()); } }
/// <summary> /// Performs a lightweight validation to determine if the source type and target type matches. /// It isn't more strict to support miscellaneous uses of the driver, like direct inputs of blobs and all that. (backward compatibility) /// </summary> public bool IsAssignableFrom(CqlColumn column, object value) { if (value == null || value is byte[]) { return true; } var type = value.GetType(); ITypeSerializer typeSerializer; if (_primitiveSerializers.TryGetValue(type, out typeSerializer)) { var cqlType = typeSerializer.CqlType; //Its a single type, if the types match -> go ahead if (cqlType == column.TypeCode) { return true; } //Only int32 and blobs are valid cql ints if (column.TypeCode == ColumnTypeCode.Int) { return false; } //Only double, longs and blobs are valid cql double if (column.TypeCode == ColumnTypeCode.Double && !(value is long)) { return false; } //The rest of the single values are not evaluated return true; } if (column.TypeCode == ColumnTypeCode.List || column.TypeCode == ColumnTypeCode.Set) { return value is IEnumerable; } if (column.TypeCode == ColumnTypeCode.Map) { return value is IDictionary; } if (column.TypeCode == ColumnTypeCode.Tuple) { return value is IStructuralComparable; } return true; }
public static object Deserialize(this CqlColumn cqlColumn, byte[] rawData) { //skip parsing and return null value when rawData is null if (rawData == null) { return(null); } object data; Type colType; switch (cqlColumn.CqlType) { default: data = Deserialize(cqlColumn.CqlType, rawData); break; case CqlType.List: if (!cqlColumn.CollectionValueType.HasValue) { throw new CqlException("CqlColumn collection type must has its value type set"); } colType = cqlColumn.CollectionValueType.Value.ToType(); Type typedColl = typeof(List <>).MakeGenericType(colType); var list = (IList)Activator.CreateInstance(typedColl); using (var ms = new MemoryStream(rawData)) { short nbElem = ms.ReadShort(); for (int i = 0; i < nbElem; i++) { byte[] elemRawData = ms.ReadShortByteArray(); object elem = Deserialize(cqlColumn.CollectionValueType.Value, elemRawData); list.Add(elem); } data = list; } break; case CqlType.Set: if (!cqlColumn.CollectionValueType.HasValue) { throw new CqlException("CqlColumn collection type must has its value type set"); } colType = cqlColumn.CollectionValueType.Value.ToType(); Type tempListType = typeof(List <>).MakeGenericType(colType); var tempList = (IList)Activator.CreateInstance(tempListType); using (var ms = new MemoryStream(rawData)) { short nbElem = ms.ReadShort(); for (int i = 0; i < nbElem; i++) { byte[] elemRawData = ms.ReadShortByteArray(); object elem = Deserialize(cqlColumn.CollectionValueType.Value, elemRawData); tempList.Add(elem); } Type typedSet = typeof(HashSet <>).MakeGenericType(colType); data = Activator.CreateInstance(typedSet, tempList); } break; case CqlType.Map: if (!cqlColumn.CollectionKeyType.HasValue) { throw new CqlException("CqlColumn map type must has its key type set"); } if (!cqlColumn.CollectionValueType.HasValue) { throw new CqlException("CqlColumn map type must has its value type set"); } Type keyType = cqlColumn.CollectionKeyType.Value.ToType(); colType = cqlColumn.CollectionValueType.Value.ToType(); Type typedDic = typeof(Dictionary <,>).MakeGenericType(keyType, colType); var dic = (IDictionary)Activator.CreateInstance(typedDic); using (var ms = new MemoryStream(rawData)) { short nbElem = ms.ReadShort(); for (int i = 0; i < nbElem; i++) { byte[] elemRawKey = ms.ReadShortByteArray(); byte[] elemRawValue = ms.ReadShortByteArray(); object key = Deserialize(cqlColumn.CollectionKeyType.Value, elemRawKey); object value = Deserialize(cqlColumn.CollectionValueType.Value, elemRawValue); dic.Add(key, value); } data = dic; } break; } return(data); }
public static byte[] Serialize(this CqlColumn cqlColumn, object data) { //null value check if (data == null) { return(null); } byte[] rawData; switch (cqlColumn.CqlType) { case CqlType.List: case CqlType.Set: if (!cqlColumn.CollectionValueType.HasValue) { throw new CqlException("CqlColumn collection type must has its value type set"); } var coll = (IEnumerable)data; using (var ms = new MemoryStream()) { //write length placeholder ms.Position = 2; short count = 0; foreach (object elem in coll) { byte[] rawDataElem = Serialize(cqlColumn.CollectionValueType.Value, elem); ms.WriteShortByteArray(rawDataElem); count++; } ms.Position = 0; ms.WriteShort(count); rawData = ms.ToArray(); } break; case CqlType.Map: if (!cqlColumn.CollectionKeyType.HasValue) { throw new CqlException("CqlColumn map type must has its key type set"); } if (!cqlColumn.CollectionValueType.HasValue) { throw new CqlException("CqlColumn map type must has its value type set"); } var map = (IDictionary)data; using (var ms = new MemoryStream()) { ms.WriteShort((short)map.Count); foreach (DictionaryEntry de in map) { byte[] rawDataKey = Serialize(cqlColumn.CollectionKeyType.Value, de.Key); ms.WriteShortByteArray(rawDataKey); byte[] rawDataValue = Serialize(cqlColumn.CollectionValueType.Value, de.Value); ms.WriteShortByteArray(rawDataValue); } rawData = ms.ToArray(); } break; default: rawData = Serialize(cqlColumn.CqlType, data); break; } return(rawData); }
/// <summary> /// Gets an Expression that represents calling Row.GetValue<T>(columnIndex) and applying any type conversion necessary to /// convert it to the destination type on the POCO. /// </summary> private Expression GetExpressionToGetColumnValueFromRow(ParameterExpression row, CqlColumn dbColumn, Type pocoDestType) { // Row.GetValue<T>(columnIndex) ConstantExpression columnIndex = Expression.Constant(dbColumn.Index, IntType); MethodCallExpression getValueT = Expression.Call(row, GetValueOfTMethod.MakeGenericMethod(dbColumn.Type), columnIndex); if (pocoDestType == dbColumn.Type) { // No casting/conversion needed since the types match exactly return(getValueT); } // Check for a converter Delegate converter = _typeConverter.GetFromDbConverter(dbColumn.Type, pocoDestType); if (converter == null) { // No converter is available but the types don't match, so attempt to do: // (TFieldOrProp) row.GetValue<T>(columnIndex); try { return(Expression.Convert(getValueT, pocoDestType)); } catch (InvalidOperationException ex) { var message = String.Format("It is not possible to convert column `{0}` of type {1} to target type {2}", dbColumn.Name, dbColumn.TypeCode, pocoDestType.Name); throw new InvalidTypeException(message, ex); } } // Invoke the converter function on getValueT (taking into account whether it's a static method): // converter(row.GetValue<T>(columnIndex)); return(Expression.Call(converter.Target == null ? null : Expression.Constant(converter.Target), converter.Method, getValueT)); }
/// <summary> /// Gets an Expression that represents calling Row.GetValue<T>(columnIndex) and applying any type conversion necessary to /// convert it to the destination type on the POCO. /// </summary> private Expression GetExpressionToGetColumnValueFromRow(ParameterExpression row, CqlColumn dbColumn, Type pocoDestType) { // Row.GetValue<T>(columnIndex) ConstantExpression columnIndex = Expression.Constant(dbColumn.Index, IntType); MethodCallExpression getValueT = Expression.Call(row, GetValueOfTMethod.MakeGenericMethod(dbColumn.Type), columnIndex); if (pocoDestType == dbColumn.Type) { // No casting/conversion needed since the types match exactly return(getValueT); } // Check for a converter Delegate converter = _typeConverter.GetFromDbConverter(dbColumn.Type, pocoDestType); if (converter == null) { // No converter is available but the types don't match, so attempt to do: // (TFieldOrProp) row.GetValue<T>(columnIndex); return(Expression.Convert(getValueT, pocoDestType)); } // Invoke the converter function on getValueT (taking into account whether it's a static method): // converter(row.GetValue<T>(columnIndex)); return(Expression.Call(converter.Target == null ? null : Expression.Constant(converter.Target), converter.Method, getValueT)); }
public bool IsAssignableFrom(CqlColumn column, object value) { return(_serializer.IsAssignableFrom(column, value)); }
/// <summary> /// Gets an Expression that represents calling Row.GetValue<T>(columnIndex) and applying any type conversion necessary to /// convert it to the destination type on the POCO. /// </summary> private Expression GetExpressionToGetColumnValueFromRow(ParameterExpression row, CqlColumn dbColumn, Type pocoDestType) { // Row.GetValue<T>(columnIndex) ConstantExpression columnIndex = Expression.Constant(dbColumn.Index, IntType); MethodCallExpression getValueT = Expression.Call(row, GetValueOfTMethod.MakeGenericMethod(dbColumn.Type), columnIndex); if (pocoDestType == dbColumn.Type) { // No casting/conversion needed since the types match exactly return(getValueT); } // Check for a converter Expression convertedValue; Delegate converter = _typeConverter.TryGetFromDbConverter(dbColumn.Type, pocoDestType); if (converter == null) { // No converter is available but the types don't match, so attempt to do: // (TFieldOrProp) row.GetValue<T>(columnIndex); try { convertedValue = Expression.Convert(getValueT, pocoDestType); } catch (InvalidOperationException ex) { var message = string.Format("It is not possible to convert column `{0}` of type {1} to target type {2}", dbColumn.Name, dbColumn.TypeCode, pocoDestType.Name); throw new InvalidTypeException(message, ex); } } else { // Invoke the converter function on getValueT (taking into account whether it's a static method): // converter(row.GetValue<T>(columnIndex)); convertedValue = Expression.Convert( Expression.Call( converter.Target == null ? null : Expression.Constant(converter.Target), GetMethod(converter), getValueT), pocoDestType); } // Cassandra will return null for empty collections, so make an effort to populate collection properties on the POCO with // empty collections instead of null in those cases if (!TryGetCreateEmptyCollectionExpression(dbColumn, pocoDestType, out Expression defaultValue)) { // poco.SomeFieldOrProp = ... createEmptyCollection ... defaultValue = Expression.Default(pocoDestType); } return(Expression.Condition(Expression.Call(row, IsNullMethod, columnIndex), defaultValue, convertedValue)); }
/// <summary> /// Creates a rowset. /// The columns are named: col_0, ..., col_n /// The rows values are: row_0_col_0, ..., row_m_col_n /// </summary> private static RowSet CreateStringsRowset(int columnLength, int rowLength, string valueModifier = null) { var columns = new List<CqlColumn>(); var columnIndexes = new Dictionary<string, int>(); for (var i = 0; i < columnLength; i++) { var c = new CqlColumn() { Index = i, Name = "col_" + i, TypeCode = ColumnTypeCode.Text, Type = typeof(string) }; columns.Add(c); columnIndexes.Add(c.Name, c.Index); } var rs = new RowSet(); for (var j = 0; j < rowLength; j++) { rs.AddRow(new Row(columns.Select(c => valueModifier + "row_" + j + "_col_" + c.Index).Cast<object>().ToArray(), columns.ToArray(), columnIndexes)); } return rs; }
public void Row_TryConvertToType_Should_Convert_Sets() { var setIntTypeInfo = new CqlColumn { TypeCode = ColumnTypeCode.Set, TypeInfo = new SetColumnInfo { KeyTypeCode = ColumnTypeCode.Int }, Type = typeof(IEnumerable<int>) }; var values = new[] { new object[] {new [] {1, 2, 3}, setIntTypeInfo, typeof(int[])}, new object[] {new [] {1, 2, 3}, setIntTypeInfo, typeof(object), typeof(int[])}, new object[] {new [] {1, 2, 3}, setIntTypeInfo, typeof(IEnumerable<int>), typeof(int[])}, new object[] {new [] {1, 2, 3}, setIntTypeInfo, typeof(HashSet<int>)}, new object[] {new [] {1, 2, 3}, setIntTypeInfo, typeof(SortedSet<int>)}, new object[] {new [] {1, 2, 3}, setIntTypeInfo, typeof(ISet<int>), typeof(List<int>)} }; foreach (var item in values) { var value = Row.TryConvertToType(item[0], (CqlColumn)item[1], (Type)item[2]); Assert.AreEqual(item.Length > 3 ? item[3] : item[2], value.GetType()); CollectionAssert.AreEqual((int[]) item[0], (IEnumerable<int>) value); } }
public void Row_TryConvertToType_Should_Convert_Timestamps() { var timestampTypeInfo = new CqlColumn {TypeCode = ColumnTypeCode.Timestamp}; var values = new[] { //column desc, value, type and expected type new object[] {DateTimeOffset.Now, timestampTypeInfo, typeof(DateTime)}, new object[] {DateTimeOffset.Now, timestampTypeInfo, typeof(DateTimeOffset)}, new object[] {DateTimeOffset.Now, timestampTypeInfo, typeof(object), typeof(DateTimeOffset)}, new object[] {DateTimeOffset.Now, timestampTypeInfo, typeof(IConvertible), typeof(DateTime)} }; foreach (var item in values) { var value = Row.TryConvertToType(item[0], (CqlColumn)item[1], (Type)item[2]); Assert.AreEqual(item.Length > 3 ? item[3] : item[2], value.GetType()); } }
/// <summary> /// Returns true if the CqlColumn is a collection type. /// </summary> private static bool IsCassandraCollection(CqlColumn dbColumn) { return(dbColumn.TypeCode == ColumnTypeCode.List || dbColumn.TypeCode == ColumnTypeCode.Set || dbColumn.TypeCode == ColumnTypeCode.Map); }
/// <summary> /// Tries to get an Expression that will create an empty collection compatible with the POCO column's type if the type coming from /// the database is a collection type. Returns true if successful, along with the Expression in an out parameter. /// </summary> private static bool TryGetCreateEmptyCollectionExpression(CqlColumn dbColumn, Type pocoDestType, out Expression createEmptyCollection) { createEmptyCollection = null; // If the DB column isn't a collection type, just bail if (IsCassandraCollection(dbColumn) == false) { return(false); } // See if the POCO's type if something we can create an empty collection for if (!pocoDestType.GetTypeInfo().IsInterface) { // If an array, we know we have a constructor available if (pocoDestType.IsArray) { // new T[] { } createEmptyCollection = Expression.NewArrayInit(pocoDestType.GetElementType()); return(true); } // Is a type implementing ICollection<T>? (this covers types implementing ISet<T>, IDictionary<T> as well) if (ImplementsCollectionInterface(pocoDestType)) { try { // new T(); createEmptyCollection = Expression.New(pocoDestType); return(true); } catch (ArgumentException) { // Type does not have an empty constructor, so just bail return(false); } } } else { // See if destination type interface on the POCO is one we can create an empty object for if (!pocoDestType.GetTypeInfo().IsGenericType) { return(false); } Type openGenericType = pocoDestType.GetGenericTypeDefinition(); // Handle IDictionary<T, U> if (openGenericType == typeof(IDictionary <,>)) { // The driver currently uses SortedDictionary so we will too Type dictionaryType = typeof(SortedDictionary <,>).MakeGenericType(pocoDestType.GetTypeInfo().GetGenericArguments()); // (IDictionary<T, U>) new SortedDictionary<T, U>(); createEmptyCollection = Expression.Convert(Expression.New(dictionaryType), pocoDestType); return(true); } // Handle ISet<T> if (openGenericType == typeof(ISet <>)) { // The driver uses List (?!) but we'll use a sorted set since that's the CQL semantics Type setType = typeof(SortedSet <>).MakeGenericType(pocoDestType.GetTypeInfo().GetGenericArguments()); // (ISet<T>) new SortedSet<T>(); createEmptyCollection = Expression.Convert(Expression.New(setType), pocoDestType); return(true); } // Handle interfaces implemented by List<T>, like ICollection<T>, IList<T>, IReadOnlyList<T>, IReadOnlyCollection<T> and IEnumerable<T> if (TypeConverter.ListGenericInterfaces.Contains(openGenericType)) { // The driver uses List so we'll use that as well Type listType = typeof(List <>).MakeGenericType(pocoDestType.GetTypeInfo().GetGenericArguments()); // (... IList<T> or ICollection<T> or IEnumerable<T> ...) new List<T>(); createEmptyCollection = Expression.Convert(Expression.New(listType), pocoDestType); return(true); } } // We don't know what to do to create an empty collection or we don't know it's a collection return(false); }