Exemple #1
0
 internal CqlCommand(Expression expression, ITable table, StatementFactory stmtFactory, PocoData pocoData)
 {
     _expression = expression;
     Table = table;
     _statementFactory = stmtFactory;
     PocoData = pocoData;
 }
Exemple #2
0
 internal CqlUpdate(Expression expression, ITable table, StatementFactory stmtFactory, PocoData pocoData)
     : base(expression, table, stmtFactory, pocoData)
 {
 }
Exemple #3
0
 internal CqlUpdate(Expression expression, ITable table, StatementFactory stmtFactory, PocoData pocoData, MapperFactory mapperFactory)
     : base(expression, table, stmtFactory, pocoData)
 {
     _mapperFactory = mapperFactory;
 }
Exemple #4
0
        /// <summary>
        /// Creates a mapper Func for a POCO.
        /// </summary>
        private Func <Row, T> CreateMapperForPoco <T>(RowSet rows, PocoData pocoData)
        {
            // We're going to store the method body expressions in a list since we need to use some looping to generate it
            ICollection <Expression> methodBodyExpressions = new LinkedList <Expression>();

            // The input parameter for our Func<Row, T>, a C* Row
            ParameterExpression row = Expression.Parameter(CassandraRowType, "row");

            // T poco = new T();
            var poco = Expression.Variable(pocoData.PocoType, "poco");

            if (pocoData.PocoType.GetTypeInfo().GetConstructor(Type.EmptyTypes) != null)
            {
                //It has default constructor
                methodBodyExpressions.Add(Expression.Assign(poco, Expression.New(pocoData.PocoType)));
            }
            else
            {
                var constructor = pocoData.PocoType.GetTypeInfo().GetConstructors().FirstOrDefault(c => c.GetParameters().Length == rows.Columns.Length);
                if (constructor == null)
                {
                    throw new ArgumentException(
                              string.Format("RowSet columns length is {0} but type {1} does not contain a constructor with the same amount of parameters",
                                            rows.Columns.Length,
                                            pocoData.PocoType));
                }
                var parameterInfos       = constructor.GetParameters();
                var parameterExpressions = new List <Expression>();
                for (var i = 0; i < rows.Columns.Length; i++)
                {
                    var c         = rows.Columns[i];
                    var param     = parameterInfos[i];
                    var getValueT = GetExpressionToGetColumnValueFromRow(row, c, param.ParameterType);
                    parameterExpressions.Add(getValueT);
                }
                methodBodyExpressions.Add(Expression.Assign(poco, Expression.New(constructor, parameterExpressions)));
            }

            // Keep track of any variables we need in the method body, starting with the poco variable
            var methodBodyVariables = new List <ParameterExpression> {
                poco
            };

            foreach (var dbColumn in rows.Columns)
            {
                // Try to find a corresponding column on the POCO and if not found, don't map that column from the RowSet
                PocoColumn pocoColumn;
                if (pocoData.Columns.TryGetItem(dbColumn.Name, out pocoColumn) == false)
                {
                    continue;
                }

                // Figure out if we're going to need to do any casting/conversion when we call Row.GetValue<T>(columnIndex)
                Expression getColumnValue = GetExpressionToGetColumnValueFromRow(row, dbColumn, pocoColumn.MemberInfoType);

                // poco.SomeFieldOrProp = ... getColumnValue call ...
                BinaryExpression getValueAndAssign = Expression.Assign(Expression.MakeMemberAccess(poco, pocoColumn.MemberInfo), getColumnValue);

                // Start with an expression that does nothing if the row is null
                Expression ifRowValueIsNull = Expression.Empty();

                // 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
                Expression createEmptyCollection;
                if (TryGetCreateEmptyCollectionExpression(dbColumn, pocoColumn.MemberInfoType, out createEmptyCollection))
                {
                    // poco.SomeFieldOrProp = ... createEmptyCollection ...
                    ifRowValueIsNull = Expression.Assign(Expression.MakeMemberAccess(poco, pocoColumn.MemberInfo), createEmptyCollection);
                }

                var columnIndex = Expression.Constant(dbColumn.Index, IntType);
                //Expression equivalent to
                // if (row.IsNull(columnIndex) == false) => getValueAndAssign ...
                // else => ifRowIsNull ...
                methodBodyExpressions.Add(Expression.IfThenElse(Expression.IsFalse(Expression.Call(row, IsNullMethod, columnIndex)),
                                                                getValueAndAssign,
                                                                ifRowValueIsNull));
            }

            // The last expression in the method body is the return value, so put our new POCO at the end
            methodBodyExpressions.Add(poco);

            // Create a block expression for the method body expressions
            BlockExpression methodBody = Expression.Block(methodBodyVariables, methodBodyExpressions);

            // Return compiled expression
            return(Expression.Lambda <Func <Row, T> >(methodBody, row).Compile());
        }
        /// <summary>
        /// Creates a mapper Func for a POCO.
        /// </summary>
        private Func <Row, T> CreateMapperForPoco <T>(RowSet rows, PocoData pocoData)
        {
            // We're going to store the method body expressions in a list since we need to use some looping to generate it
            var methodBodyExpressions = new List <Expression>();

            // The input parameter for our Func<Row, T>, a C* Row
            ParameterExpression row = Expression.Parameter(CassandraRowType, "row");

            // T poco = new T();
            var poco = Expression.Variable(pocoData.PocoType, "poco");

            if (pocoData.PocoType.GetConstructor(Type.EmptyTypes) != null)
            {
                //It has default constructor
                methodBodyExpressions.Add(Expression.Assign(poco, Expression.New(pocoData.PocoType)));
            }
            else
            {
                var constructor = pocoData.PocoType.GetConstructors().FirstOrDefault(c => c.GetParameters().Length == rows.Columns.Length);
                if (constructor == null)
                {
                    throw new ArgumentException(
                              String.Format("RowSet columns length is {0} but type {1} does not contain a constructor with the same amount of parameters",
                                            rows.Columns.Length,
                                            pocoData.PocoType));
                }
                var parameterInfos       = constructor.GetParameters();
                var parameterExpressions = new List <Expression>();
                for (var i = 0; i < rows.Columns.Length; i++)
                {
                    var c         = rows.Columns[i];
                    var param     = parameterInfos[i];
                    var getValueT = GetExpressionToGetColumnValueFromRow(row, c, param.ParameterType);
                    parameterExpressions.Add(getValueT);
                }
                methodBodyExpressions.Add(Expression.Assign(poco, Expression.New(constructor, parameterExpressions)));
            }

            // Keep track of any variables we need in the method body, starting with the poco variable
            var methodBodyVariables = new List <ParameterExpression> {
                poco
            };

            foreach (var dbColumn in rows.Columns)
            {
                // Try to find a corresponding column on the POCO and if not found, don't map that column from the RowSet
                PocoColumn pocoColumn;
                if (pocoData.Columns.TryGetItem(dbColumn.Name, out pocoColumn) == false)
                {
                    continue;
                }

                // Figure out if we're going to need to do any casting/conversion when we call Row.GetValue<T>(columnIndex)
                Expression       getColumnValue = GetExpressionToGetColumnValueFromRow(row, dbColumn, pocoColumn.MemberInfoType);
                BinaryExpression assignValue    = Expression.Assign(Expression.MakeMemberAccess(poco, pocoColumn.MemberInfo), getColumnValue);

                methodBodyExpressions.Add(assignValue);
            }

            // The last expression in the method body is the return value, so put our new POCO at the end
            methodBodyExpressions.Add(poco);

            // Create a block expression for the method body expressions
            BlockExpression methodBody = Expression.Block(methodBodyVariables, methodBodyExpressions);

            // Return compiled expression
            return(Expression.Lambda <Func <Row, T> >(methodBody, row).Compile());
        }