internal CqlCommand(Expression expression, ITable table, StatementFactory stmtFactory, PocoData pocoData) { _expression = expression; Table = table; _statementFactory = stmtFactory; PocoData = pocoData; }
internal CqlUpdate(Expression expression, ITable table, StatementFactory stmtFactory, PocoData pocoData) : base(expression, table, stmtFactory, pocoData) { }
internal CqlUpdate(Expression expression, ITable table, StatementFactory stmtFactory, PocoData pocoData, MapperFactory mapperFactory) : base(expression, table, stmtFactory, pocoData) { _mapperFactory = mapperFactory; }
/// <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()); }