예제 #1
0
        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);
        }
예제 #2
0
        /// <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());
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        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}");
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
 /// <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;
 }
예제 #8
0
        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);
            }
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        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++;
                }
            }
        }
예제 #11
0
        /// <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());
        }
예제 #12
0
        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++;
                }
            }
        }
예제 #13
0
        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++;
                }
            }
        }
예제 #14
0
        /// <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);
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
        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));
            }
        }
예제 #17
0
        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());
            }
        }
예제 #18
0
        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());
            }
        }
예제 #19
0
        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());
            }
        }
예제 #20
0
        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));
            }
        }
예제 #21
0
        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());
            }
        }
예제 #22
0
 /// <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;
 }
예제 #23
0
        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);
        }
예제 #24
0
        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);
        }
예제 #25
0
        /// <summary>
        /// Gets an Expression that represents calling Row.GetValue&lt;T&gt;(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));
        }
예제 #26
0
        /// <summary>
        /// Gets an Expression that represents calling Row.GetValue&lt;T&gt;(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));
        }
예제 #27
0
 public bool IsAssignableFrom(CqlColumn column, object value)
 {
     return(_serializer.IsAssignableFrom(column, value));
 }
예제 #28
0
        /// <summary>
        /// Gets an Expression that represents calling Row.GetValue&lt;T&gt;(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));
        }
예제 #29
0
 /// <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;
 }
예제 #30
0
 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);
     }
 }
예제 #31
0
 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());
     }
 }
예제 #32
0
 /// <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);
 }
예제 #33
0
        /// <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);
        }