Beispiel #1
0
        private static DbModificationCommandTree RebuildCommandTree(
            DbModificationCommandTree originalTree, Dictionary <DbSetClause, DbSetClause> clauseMappings)
        {
            if (clauseMappings.Count == 0)
            {
                return(originalTree);
            }

            DbModificationCommandTree result;

            Debug.Assert(
                originalTree.CommandTreeKind == DbCommandTreeKind.Insert || originalTree.CommandTreeKind == DbCommandTreeKind.Update,
                "Set clauses specified for a modification tree that is not an update or insert tree?");
            if (originalTree.CommandTreeKind
                == DbCommandTreeKind.Insert)
            {
                var insertTree = (DbInsertCommandTree)originalTree;
                result = new DbInsertCommandTree(
                    insertTree.MetadataWorkspace, insertTree.DataSpace,
                    insertTree.Target, new ReadOnlyCollection <DbModificationClause>(ReplaceClauses(insertTree.SetClauses, clauseMappings)), insertTree.Returning);
            }
            else
            {
                var updateTree = (DbUpdateCommandTree)originalTree;
                result = new DbUpdateCommandTree(
                    updateTree.MetadataWorkspace, updateTree.DataSpace,
                    updateTree.Target, updateTree.Predicate, new ReadOnlyCollection <DbModificationClause>(ReplaceClauses(updateTree.SetClauses, clauseMappings)),
                    updateTree.Returning);
            }

            return(result);
        }
 public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
 {
     if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
     {
         var insertCommand = interceptionContext.Result as DbInsertCommandTree;
         if (insertCommand != null)
         {
             var newSetClauses = GenerateSetClauses(insertCommand.SetClauses);
             var newCommand    = new DbInsertCommandTree(
                 insertCommand.MetadataWorkspace,
                 insertCommand.DataSpace,
                 insertCommand.Target,
                 newSetClauses,
                 insertCommand.Returning);
             interceptionContext.Result = newCommand;
         }
         var updateCommand = interceptionContext.Result as DbUpdateCommandTree;
         if (updateCommand != null)
         {
             var newSetClauses = GenerateSetClauses(updateCommand.SetClauses);
             var newCommand    = new DbUpdateCommandTree(
                 updateCommand.MetadataWorkspace,
                 updateCommand.DataSpace,
                 updateCommand.Target,
                 updateCommand.Predicate,
                 newSetClauses,
                 updateCommand.Returning);
             interceptionContext.Result = newCommand;
         }
     }
 }
Beispiel #3
0
        /// <summary>
        ///     Builds an update command.
        /// </summary>
        /// <param name="oldRow"> Old value of the row being updated. </param>
        /// <param name="newRow"> New value for the row being updated. </param>
        /// <param name="processor"> Context for the table containing row. </param>
        /// <returns> Update command. </returns>
        internal UpdateCommand BuildUpdateCommand(
            PropagatorResult oldRow,
            PropagatorResult newRow, TableChangeProcessor processor)
        {
            // If we're updating a row, the row may not need to be touched (e.g., no concurrency validation required)
            var rowMustBeTouched = false;

            var target = GetTarget(processor);

            // Create set clauses and returning parameter
            Dictionary <int, string> outputIdentifiers;
            DbExpression             returning;
            var setClauses = new List <DbModificationClause>();

            foreach (var clause in BuildSetClauses(
                         target, newRow, oldRow, processor, /* insertMode */ false, out outputIdentifiers, out returning,
                         ref rowMustBeTouched))
            {
                setClauses.Add(clause);
            }

            // Construct predicate identifying the row to modify
            var predicate = BuildPredicate(target, oldRow, newRow, processor, ref rowMustBeTouched);

            if (0 == setClauses.Count)
            {
                if (rowMustBeTouched)
                {
                    var stateEntries = new List <IEntityStateEntry>();
                    stateEntries.AddRange(
                        SourceInterpreter.GetAllStateEntries(
                            oldRow, m_translator, processor.Table));
                    stateEntries.AddRange(
                        SourceInterpreter.GetAllStateEntries(
                            newRow, m_translator, processor.Table));
                    if (stateEntries.All(it => (it.State == EntityState.Unchanged)))
                    {
                        rowMustBeTouched = false;
                    }
                }

                // Determine if there is nothing to do (i.e., no values to set,
                // no computed columns, and no concurrency validation required)
                if (!rowMustBeTouched)
                {
                    return(null);
                }
            }

            // Initialize DML command tree
            var commandTree =
                new DbUpdateCommandTree(
                    m_translator.MetadataWorkspace, DataSpace.SSpace, target, predicate, setClauses.AsReadOnly(), returning);

            // Create command
            UpdateCommand command = new DynamicUpdateCommand(
                processor, m_translator, ModificationOperator.Update, oldRow, newRow, commandTree, outputIdentifiers);

            return(command);
        }
Beispiel #4
0
        private DbCommandTree HandleUpdateCommand(DbUpdateCommandTree updateCommand)
        {
            var target       = updateCommand.Target;
            var variableType = target.VariableType;
            var entityType   = (EntityType)variableType.EdmType;

            if (entityType.Properties.All(p => p.Name != Constants.CREATED_COLUMN_NAME && p.Name != Constants.MODIFIED_COLUMN_NAME))
            {
                return(updateCommand);
            }

            var now = m_DateTimeProvider.GetUtcNow();

            var setClauses = updateCommand.SetClauses
                             .Select(clause => clause.UpdateIfMatch(Constants.MODIFIED_COLUMN_NAME, DbExpression.FromDateTime(now)))
                             .ToList();

            return(new DbUpdateCommandTree(
                       updateCommand.MetadataWorkspace,
                       updateCommand.DataSpace,
                       updateCommand.Target,
                       updateCommand.Predicate,
                       setClauses.AsReadOnly(),
                       updateCommand.Returning));
        }
        internal static string GenerateUpdateSql(DbUpdateCommandTree tree, out List <DbParameter> parameters)
        {
            StringBuilder        commandText = new StringBuilder(s_commandTextBuilderInitialCapacity);
            ExpressionTranslator translator  = new ExpressionTranslator(commandText, tree, null != tree.Returning);

            // update [schemaName].[tableName]
            commandText.Append("update ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // set c1 = ..., c2 = ..., ...
            bool first = true;

            commandText.Append("set ");
            foreach (DbSetClause setClause in tree.SetClauses)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept(translator);
                commandText.Append(" = ");
                setClause.Value.Accept(translator);
            }

            if (first)
            {
                //// If first is still true, it indicates there were no set
                //// clauses. Introduce a fake set clause so that:
                //// - we acquire the appropriate locks
                //// - server-gen columns (e.g. timestamp) get recomputed
                ////
                //// We use the following pattern:
                ////
                ////  update Foo
                ////  set @i = 0
                ////  where ...
                //IngresParameter parameter = translator.CreateParameter(default(Int32), IngresType.Int);
                //commandText.Append(parameter.ParameterName);
                //commandText.Append(" = 0");
                parameters = new List <DbParameter>();
                return(string.Empty);
            }
            commandText.AppendLine();

            // where c1 = ..., c2 = ...
            commandText.Append("where ");
            tree.Predicate.Accept(translator);
            commandText.AppendLine();

            // generate returning sql
            GenerateReturningSql(commandText, tree, translator, tree.Returning);

            parameters = translator.Parameters;
            return(commandText.ToString());
        }
Beispiel #6
0
 public VfpExpression Visit(DbUpdateCommandTree commandTree)
 {
     return(new VfpUpdateCommandTree(CreateDbExpressionBinding(commandTree.Target),
                                     CreateDbSetClauses(commandTree.SetClauses),
                                     commandTree.Predicate.Accept(this),
                                     commandTree.Parameters,
                                     commandTree.Returning == null ? null : commandTree.Returning.Accept(this)));
 }
Beispiel #7
0
        internal string Print(DbUpdateCommandTree tree)
        {
            // Predicate should not be null since DbUpdateCommandTree initializes it to DbConstantExpression(true)
            Debug.Assert(tree != null && tree.Predicate != null, "Invalid DbUpdateCommandTree");

            TreeNode targetNode = null;

            if (tree.Target != null)
            {
                targetNode = _visitor.VisitBinding("Target", tree.Target);
            }
            else
            {
                targetNode = new TreeNode("Target");
            }

            var clausesNode = new TreeNode("SetClauses");

            foreach (var clause in tree.SetClauses)
            {
                if (clause != null)
                {
                    clausesNode.Children.Add(clause.Print(_visitor));
                }
            }

            TreeNode predicateNode;

            if (null != tree.Predicate)
            {
                predicateNode = new TreeNode("Predicate", _visitor.VisitExpression(tree.Predicate));
            }
            else
            {
                predicateNode = new TreeNode("Predicate");
            }

            TreeNode returningNode;

            if (null != tree.Returning)
            {
                returningNode = new TreeNode("Returning", _visitor.VisitExpression(tree.Returning));
            }
            else
            {
                returningNode = new TreeNode("Returning");
            }

            return(Print(
                       new TreeNode(
                           "DbUpdateCommandTree",
                           CreateParametersNode(tree),
                           targetNode,
                           clausesNode,
                           predicateNode,
                           returningNode)));
        }
        private void GetAffectedEntitySets(DbCommandTree commandTree)
        {
            FindAffectedEntitySetsVisitor visitor   = new FindAffectedEntitySetsVisitor(this.affectedEntitySets, this.functionsUsed);
            DbQueryCommandTree            queryTree = commandTree as DbQueryCommandTree;

            if (queryTree != null)
            {
                queryTree.Query.Accept(visitor);
                return;
            }

            DbUpdateCommandTree updateTree = commandTree as DbUpdateCommandTree;

            if (updateTree != null)
            {
                this.IsModification = true;
                updateTree.Target.Expression.Accept(visitor);
                updateTree.Predicate.Accept(visitor);
                if (updateTree.Returning != null)
                {
                    updateTree.Returning.Accept(visitor);
                }

                return;
            }

            DbInsertCommandTree insertTree = commandTree as DbInsertCommandTree;

            if (insertTree != null)
            {
                this.IsModification = true;
                insertTree.Target.Expression.Accept(visitor);
                if (insertTree.Returning != null)
                {
                    insertTree.Returning.Accept(visitor);
                }

                return;
            }

            DbDeleteCommandTree deleteTree = commandTree as DbDeleteCommandTree;

            if (deleteTree != null)
            {
                this.IsModification = true;
                deleteTree.Target.Expression.Accept(visitor);
                if (deleteTree.Predicate != null)
                {
                    deleteTree.Predicate.Accept(visitor);
                }

                return;
            }

            throw new NotSupportedException("Command tree type " + commandTree.GetType() + " is not supported.");
        }
        public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
        {
            if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
            {
                var queryCommand = interceptionContext.Result as DbQueryCommandTree;

                if (queryCommand != null)
                {
                    var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());

                    interceptionContext.Result = new DbQueryCommandTree(
                        queryCommand.MetadataWorkspace,
                        queryCommand.DataSpace,
                        newQuery);
                }

                var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;

                if (deleteCommand != null)
                {
                    var column = SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType);

                    if (column != null)
                    {
                        // Just because the entity has the soft delete annotation doesn't mean that
                        // this particular table has the column. This occurs in situation like TPT
                        // inheritance mapping and entity splitting where one type maps to multiple
                        // tables.
                        // If the table doesn't have the column we just want to leave the row unchanged
                        // since it will be joined to the table that does have the column during query.
                        // We can't no-op, so we just generate an UPDATE command that doesn't set anything.
                        var setClauses = new List <DbModificationClause>();
                        var table      = (EntityType)deleteCommand.Target.VariableType.EdmType;

                        if (table.Properties.Any(p => p.Name == column))
                        {
                            setClauses.Add(DbExpressionBuilder.SetClause(
                                               DbExpressionBuilder.Property(
                                                   DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName),
                                                   column),
                                               DbExpression.FromBoolean(true)));
                        }

                        var update = new DbUpdateCommandTree(
                            deleteCommand.MetadataWorkspace,
                            deleteCommand.DataSpace,
                            deleteCommand.Target,
                            deleteCommand.Predicate,
                            setClauses.AsReadOnly(),
                            null);

                        interceptionContext.Result = update;
                    }
                }
            }
        }
		internal static string GenerateUpdateSql(DbUpdateCommandTree tree, out List<DbParameter> parameters, bool generateParameters = true)
		{
			StringBuilder commandText = new StringBuilder(CommandTextBuilderInitialCapacity);
			ExpressionTranslator translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, generateParameters);
			bool first = true;

			commandText.Append("UPDATE ");
			tree.Target.Expression.Accept(translator);
			commandText.AppendLine();

			// set c1 = ..., c2 = ..., ...
			commandText.Append("SET ");

			foreach (DbSetClause setClause in tree.SetClauses)
			{
				if (first)
				{
					first = false;
				}
				else
				{
					commandText.Append(", ");
				}

				setClause.Property.Accept(translator);
				commandText.Append(" = ");
				setClause.Value.Accept(translator);

				translator.RegisterMemberValue(setClause.Property, setClause.Value);
			}

			if (first)
			{
				// If first is still true, it indicates there were no set
				// clauses. Introduce a fake set clause so that:
				// - we acquire the appropriate locks
				// - server-gen columns (e.g. timestamp) get recomputed

				EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target;
				// hope this column isn't indexed to not waste power
				EdmMember someColumn = table.ElementType.Members.Last(x => !MetadataHelpers.IsStoreGenerated(x));
				commandText.AppendFormat("{0} = {0}", GenerateMemberSql(someColumn));
			}
			commandText.AppendLine();

			// where c1 = ..., c2 = ...
			commandText.Append("WHERE ");
			tree.Predicate.Accept(translator);
			commandText.AppendLine();

			// generate returning sql
			GenerateReturningSql(commandText, tree, translator, tree.Returning);

			parameters = translator.Parameters;
			return commandText.ToString();
		}
Beispiel #11
0
        internal static string GenerateUpdateSql(DbUpdateCommandTree tree, out List <DbParameter> parameters, bool generateParameters = true)
        {
            StringBuilder        commandText = new StringBuilder(CommandTextBuilderInitialCapacity);
            ExpressionTranslator translator  = new ExpressionTranslator(commandText, tree, null != tree.Returning, generateParameters);
            bool first = true;

            commandText.Append("UPDATE ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // set c1 = ..., c2 = ..., ...
            commandText.Append("SET ");

            foreach (DbSetClause setClause in tree.SetClauses)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    commandText.Append(", ");
                }

                setClause.Property.Accept(translator);
                commandText.Append(" = ");
                setClause.Value.Accept(translator);

                translator.RegisterMemberValue(setClause.Property, setClause.Value);
            }

            if (first)
            {
                // If first is still true, it indicates there were no set
                // clauses. Introduce a fake set clause so that:
                // - we acquire the appropriate locks
                // - server-gen columns (e.g. timestamp) get recomputed

                EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target;
                // hope this column isn't indexed to not waste power
                EdmMember someColumn = table.ElementType.Members.Last(x => !MetadataHelpers.IsStoreGenerated(x));
                commandText.AppendFormat("{0} = {0}", GenerateMemberSql(someColumn));
            }
            commandText.AppendLine();

            // where c1 = ..., c2 = ...
            commandText.Append("WHERE ");
            tree.Predicate.Accept(translator);
            commandText.AppendLine();

            // generate returning sql
            GenerateReturningSql(commandText, tree, translator, tree.Returning);

            parameters = translator.Parameters;
            return(commandText.ToString());
        }
Beispiel #12
0
        private DbModificationCommandTree ConvertInternal(
            DbUpdateCommandTree commandTree)
        {
            this._currentFunctionMapping = this._entityTypeModificationFunctionMapping.UpdateFunctionMapping;
            this._useOriginalValues      = true;
            DbExpression predicate = commandTree.Predicate.Accept <DbExpression>((DbExpressionVisitor <DbExpression>) this);

            this._useOriginalValues = false;
            return((DbModificationCommandTree) new DbUpdateCommandTree(commandTree.MetadataWorkspace, commandTree.DataSpace, commandTree.Target, predicate, this.VisitSetClauses(commandTree.SetClauses), commandTree.Returning != null ? commandTree.Returning.Accept <DbExpression>((DbExpressionVisitor <DbExpression>) this) : (DbExpression)null));
        }
Beispiel #13
0
        /// <summary>
        /// General purpose static function that can be called from System.Data assembly
        /// </summary>
        /// <param name="tree">command tree</param>
        /// <param name="version">version</param>
        /// <param name="parameters">Parameters to add to the command tree corresponding
        /// to constants in the command tree. Used only in ModificationCommandTrees.</param>
        /// <returns>The string representing the SQL to be executed.</returns>
        internal static string GenerateSql(DbCommandTree tree, EFIngresStoreVersion version, out List <DbParameter> parameters, out CommandType commandType)
        {
            commandType = CommandType.Text;

            //Handle Query
            DbQueryCommandTree queryCommandTree = tree as DbQueryCommandTree;

            if (queryCommandTree != null)
            {
                SqlGenerator sqlGen = new SqlGenerator(version);
                parameters = null;
                return(sqlGen.GenerateSql((DbQueryCommandTree)tree));
            }

            //Handle Function
            DbFunctionCommandTree DbFunctionCommandTree = tree as DbFunctionCommandTree;

            if (DbFunctionCommandTree != null)
            {
                SqlGenerator sqlGen = new SqlGenerator(version);
                parameters = null;

                string sql = sqlGen.GenerateFunctionSql(DbFunctionCommandTree, out commandType);

                return(sql);
            }

            //Handle Insert
            DbInsertCommandTree insertCommandTree = tree as DbInsertCommandTree;

            if (insertCommandTree != null)
            {
                return(DmlSqlGenerator.GenerateInsertSql(insertCommandTree, out parameters));
            }

            //Handle Delete
            DbDeleteCommandTree deleteCommandTree = tree as DbDeleteCommandTree;

            if (deleteCommandTree != null)
            {
                return(DmlSqlGenerator.GenerateDeleteSql(deleteCommandTree, out parameters));
            }

            //Handle Update
            DbUpdateCommandTree updateCommandTree = tree as DbUpdateCommandTree;

            if (updateCommandTree != null)
            {
                return(DmlSqlGenerator.GenerateUpdateSql(updateCommandTree, out parameters));
            }

            throw new NotSupportedException("Unrecognized command tree type");
        }
        internal static string GenerateUpdateSql(
            DbUpdateCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords    = true)
        {
            SqlStringBuilder commandText = new SqlStringBuilder(256)
            {
                UpperCaseKeywords = upperCaseKeywords
            };

            DmlSqlGenerator.ExpressionTranslator translator = new DmlSqlGenerator.ExpressionTranslator(commandText, (DbModificationCommandTree)tree, null != tree.Returning, sqlGenerator, (ICollection <EdmProperty>)null, true);
            if (tree.SetClauses.Count == 0)
            {
                commandText.AppendKeyword("declare ");
                commandText.AppendLine("@p int");
            }
            commandText.AppendKeyword("update ");
            tree.Target.Expression.Accept((DbExpressionVisitor)translator);
            commandText.AppendLine();
            bool flag = true;

            commandText.AppendKeyword("set ");
            foreach (DbSetClause setClause in (IEnumerable <DbModificationClause>)tree.SetClauses)
            {
                if (flag)
                {
                    flag = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept((DbExpressionVisitor)translator);
                commandText.Append(" = ");
                setClause.Value.Accept((DbExpressionVisitor)translator);
            }
            if (flag)
            {
                commandText.Append("@p = 0");
            }
            commandText.AppendLine();
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept((DbExpressionVisitor)translator);
            commandText.AppendLine();
            if (generateReturningSql)
            {
                DmlSqlGenerator.GenerateReturningSql(commandText, (DbModificationCommandTree)tree, (EntityType)null, translator, tree.Returning, false);
            }
            parameters = translator.Parameters;
            return(commandText.ToString());
        }
Beispiel #15
0
        public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
        {
            if (interceptionContext.OriginalResult.DataSpace != DataSpace.SSpace)
            {
                return;
            }

            var queryCommand = interceptionContext.Result as DbQueryCommandTree;

            if (queryCommand != null)
            {
                var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());
                interceptionContext.Result = new DbQueryCommandTree(
                    queryCommand.MetadataWorkspace,
                    queryCommand.DataSpace,
                    newQuery);
            }

            var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;

            if (deleteCommand == null)
            {
                return;
            }

            var column = SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType);

            if (column == null)
            {
                return;
            }

            var setClauses = new List <DbModificationClause>();
            var table      = (EntityType)deleteCommand.Target.VariableType.EdmType;

            if (table.Properties.Any(p => p.Name == column))
            {
                setClauses.Add(DbExpressionBuilder.SetClause(
                                   deleteCommand.Target.VariableType.Variable(deleteCommand.Target.VariableName).Property(column),
                                   DbExpression.FromBoolean(true)));
            }

            var update = new DbUpdateCommandTree(
                deleteCommand.MetadataWorkspace,
                deleteCommand.DataSpace,
                deleteCommand.Target,
                deleteCommand.Predicate,
                setClauses.AsReadOnly(),
                null);

            interceptionContext.Result = update;
        }
Beispiel #16
0
        /// <summary>
        /// In case of an update command we always filter based on the userId
        /// </summary>
        private static bool InterceptUpdate(DbCommandTreeInterceptionContext interceptionContext)
        {
            var updateCommand = interceptionContext.Result as DbUpdateCommandTree;

            if (updateCommand != null)
            {
                var column = UserAwareAttribute.GetUserColumnName(updateCommand.Target.VariableType.EdmType);
                if (!string.IsNullOrEmpty(column))
                {
                    // Validate user
                    Security.ValidateCurrentUser();

                    // Get the userId (throw an exception if there is none)
                    var userId = GetCurrentUserId();

                    // Create the variable reference in order to create the property
                    var variableReference = DbExpressionBuilder.Variable(updateCommand.Target.VariableType,
                                                                         updateCommand.Target.VariableName);
                    // Create the property to which will assign the correct value
                    var userProperty = DbExpressionBuilder.Property(variableReference, column);
                    // Create the userId where predicate, object representation of sql where userId = value statement
                    var userIdWherePredicate = DbExpressionBuilder.Equal(userProperty, DbExpression.FromInt32(userId));

                    // Remove potential assignment of userId for extra safety
                    var filteredSetClauses =
                        updateCommand.SetClauses.Cast <DbSetClause>()
                        .Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != column);

                    // Construct the final clauses, object representation of sql insert command values
                    var finalSetClauses =
                        new ReadOnlyCollection <DbModificationClause>(new List <DbModificationClause>(filteredSetClauses));

                    // The initial predicate is the sql where statement
                    var initialPredicate = updateCommand.Predicate;
                    // Add to the initial statement the userId statement which translates in sql AND UserId = 'value'
                    var finalPredicate = initialPredicate.And(userIdWherePredicate);

                    var newUpdateCommand = new DbUpdateCommandTree(
                        updateCommand.MetadataWorkspace,
                        updateCommand.DataSpace,
                        updateCommand.Target,
                        finalPredicate,
                        finalSetClauses,
                        updateCommand.Returning);

                    interceptionContext.Result = newUpdateCommand;
                    // True means an interception successfully happened so there is no need to continue
                    return(true);
                }
            }
            return(false);
        }
    internal static string GenerateUpdateSql(DbUpdateCommandTree tree, out List<DbParameter> parameters)
    {
      StringBuilder commandText = new StringBuilder(s_commandTextBuilderInitialCapacity);
      ExpressionTranslator translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, "UpdateFunction");

      // update [schemaName].[tableName]
      commandText.Append("UPDATE ");
      tree.Target.Expression.Accept(translator);
      commandText.AppendLine();

      // set c1 = ..., c2 = ..., ...
      bool first = true;
      commandText.Append("SET ");
      foreach (DbSetClause setClause in tree.SetClauses)
      {
        if (first) { first = false; }
        else { commandText.Append(", "); }
        setClause.Property.Accept(translator);
        commandText.Append(" = ");
        setClause.Value.Accept(translator);
      }

      if (first)
      {
        // If first is still true, it indicates there were no set
        // clauses. Introduce a fake set clause so that:
        // - we acquire the appropriate locks
        // - server-gen columns (e.g. timestamp) get recomputed
        //
        // We use the following pattern:
        //
        //  update Foo
        //  set @i = 0
        //  where ...
        DbParameter parameter = translator.CreateParameter(default(Int32), DbType.Int32);
        commandText.Append(parameter.ParameterName);
        commandText.Append(" = 0");
      }
      commandText.AppendLine();

      // where c1 = ..., c2 = ...
      commandText.Append("WHERE ");
      tree.Predicate.Accept(translator);
      commandText.AppendLine(";");

      // generate returning sql
      GenerateReturningSql(commandText, tree, translator, tree.Returning);

      parameters = translator.Parameters;
      return commandText.ToString();
    }
Beispiel #18
0
        private static DbCommandTree HandleUpdateCommand(DbUpdateCommandTree updateCommand, DateTime dateTime)
        {
            var setClauses = updateCommand.SetClauses
                             .Where(clause => !clause.IsFor(CreatedColumnName))
                             .Select(clause => clause.UpdateIfMatch(ModifiedColumnName, DbExpression.FromDateTime(dateTime)))
                             .ToList();

            return(new DbUpdateCommandTree(
                       updateCommand.MetadataWorkspace,
                       updateCommand.DataSpace,
                       updateCommand.Target,
                       updateCommand.Predicate,
                       setClauses.AsReadOnly(), null));
        }
Beispiel #19
0
        private static DbUpdateCommandTree HandleUpdateCommand(DbUpdateCommandTree updateCommand)
        {
            var newSetClauses = GenerateSetClauses(updateCommand.SetClauses);

            var newCommand = new DbUpdateCommandTree(
                updateCommand.MetadataWorkspace,
                updateCommand.DataSpace,
                updateCommand.Target,
                updateCommand.Predicate,
                newSetClauses,
                updateCommand.Returning);

            return(newCommand);
        }
Beispiel #20
0
        /// <summary>
        /// In case of an update command we always filter based on the tenantId
        /// </summary>
        private static bool InterceptUpdate(DbCommandTreeInterceptionContext interceptionContext, string tenantValue)
        {
            var updateCommand = interceptionContext.Result as DbUpdateCommandTree;

            if (updateCommand == null)
            {
                return(false);
            }

            var column = TenantAttribute.GetTenantColumnName(updateCommand.Target.VariableType.EdmType);

            if (string.IsNullOrEmpty(column))
            {
                return(false);
            }

            // Create the variable reference in order to create the property
            var variableReference = updateCommand.Target.VariableType.Variable(updateCommand.Target.VariableName);
            // Create the property to which will assign the correct value
            var tenantProperty = variableReference.Property(column);
            // Create the tenantId where predicate, object representation of sql where tenantId = value statement
            var tenantIdWherePredicate = tenantProperty.Equal(DbExpression.FromString(tenantValue));

            // Remove potential assignment of tenantId for extra safety
            var filteredSetClauses =
                updateCommand.SetClauses.Cast <DbSetClause>()
                .Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != column);

            // Construct the final clauses, object representation of sql insert command values
            var finalSetClauses =
                new ReadOnlyCollection <DbModificationClause>(new List <DbModificationClause>(filteredSetClauses));

            // The initial predicate is the sql where statement
            var initialPredicate = updateCommand.Predicate;
            // Add to the initial statement the tenantId statement which translates in sql AND TenantId = 'value'
            var finalPredicate = initialPredicate.And(tenantIdWherePredicate);

            var newUpdateCommand = new DbUpdateCommandTree(
                updateCommand.MetadataWorkspace,
                updateCommand.DataSpace,
                updateCommand.Target,
                finalPredicate,
                finalSetClauses,
                updateCommand.Returning);

            interceptionContext.Result = newUpdateCommand;
            // True means an interception successfully happened so there is no need to continue
            return(true);
        }
        private DbModificationCommandTree ConvertInternal(DbUpdateCommandTree commandTree)
        {
            DebugCheck.NotNull(commandTree);

            _currentFunctionMapping = _entityTypeModificationFunctionMapping.UpdateFunctionMapping;

            return
                (new DbUpdateCommandTree(
                     commandTree.MetadataWorkspace,
                     commandTree.DataSpace,
                     commandTree.Target,
                     commandTree.Predicate.Accept(this),
                     VisitSetClauses(commandTree.SetClauses),
                     commandTree.Returning != null ? commandTree.Returning.Accept(this) : null));
        }
Beispiel #22
0
        private static DbCommandTree HandleUpdateCommand(DbUpdateCommandTree updateCommand)
        {
            DateTime?now = DateTime.Now;

            var setClauses = updateCommand.SetClauses
                             .Select(clause => clause.UpdateIfMatch(ModifiedColumnName, DbExpression.FromDateTime(now)))
                             .ToList();

            return(new DbUpdateCommandTree(
                       updateCommand.MetadataWorkspace,
                       updateCommand.DataSpace,
                       updateCommand.Target,
                       updateCommand.Predicate,
                       setClauses.AsReadOnly(), null));
        }
Beispiel #23
0
        public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
        {
            if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
            {
                var queryCommand = interceptionContext.Result as DbQueryCommandTree;
                if (queryCommand != null)
                {
                    var context = (DataContext)interceptionContext.DbContexts.Single(c => c is DataContext);

                    if (context.SoftDeleteFilterIsActive)
                    {
                        var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());
                        interceptionContext.Result = new DbQueryCommandTree(
                            queryCommand.MetadataWorkspace,
                            queryCommand.DataSpace,
                            newQuery);
                    }
                }

                var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;
                if (deleteCommand != null)
                {
                    var column = SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType);
                    if (column != null)
                    {
                        var setClause =
                            DbExpressionBuilder.SetClause(
                                DbExpressionBuilder.Property(
                                    DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName),
                                    column),
                                DbExpression.FromBoolean(true));

                        var update = new DbUpdateCommandTree(
                            deleteCommand.MetadataWorkspace,
                            deleteCommand.DataSpace,
                            deleteCommand.Target,
                            deleteCommand.Predicate,
                            new List <DbModificationClause> {
                            setClause
                        }.AsReadOnly(),
                            null);

                        interceptionContext.Result = update;
                    }
                }
            }
        }
Beispiel #24
0
        internal string Print(DbUpdateCommandTree tree)
        {
            TreeNode treeNode1 = tree.Target == null ? new TreeNode("Target", new TreeNode[0]) : this._visitor.VisitBinding("Target", tree.Target);
            TreeNode treeNode2 = new TreeNode("SetClauses", new TreeNode[0]);

            foreach (DbModificationClause setClause in (IEnumerable <DbModificationClause>)tree.SetClauses)
            {
                if (setClause != null)
                {
                    treeNode2.Children.Add(setClause.Print((DbExpressionVisitor <TreeNode>) this._visitor));
                }
            }
            TreeNode treeNode3;

            if (tree.Predicate != null)
            {
                treeNode3 = new TreeNode("Predicate", new TreeNode[1]
                {
                    this._visitor.VisitExpression(tree.Predicate)
                });
            }
            else
            {
                treeNode3 = new TreeNode("Predicate", new TreeNode[0]);
            }
            TreeNode treeNode4;

            if (tree.Returning != null)
            {
                treeNode4 = new TreeNode("Returning", new TreeNode[1]
                {
                    this._visitor.VisitExpression(tree.Returning)
                });
            }
            else
            {
                treeNode4 = new TreeNode("Returning", new TreeNode[0]);
            }
            return(this.Print(new TreeNode("DbUpdateCommandTree", new TreeNode[5]
            {
                ExpressionPrinter.CreateParametersNode((DbCommandTree)tree),
                treeNode1,
                treeNode2,
                treeNode3,
                treeNode4
            })));
        }
        internal static string GenerateUpdateSql(DbUpdateCommandTree tree, EFOracleProviderManifest providerManifest, EFOracleVersion sqlVersion, out List <OracleParameter> parameters)
        {
            StringBuilder commandText = new StringBuilder(256);

            DmlSqlGenerator.ExpressionTranslator translator = new DmlSqlGenerator.ExpressionTranslator(commandText, (DbModificationCommandTree)tree, null != tree.Returning, sqlVersion);
            int count = tree.SetClauses.Count;

            commandText.Append("update ");
            tree.Target.Expression.Accept((DbExpressionVisitor)translator);
            commandText.AppendLine();
            bool flag = true;

            commandText.Append("set ");
            foreach (DbSetClause setClause in (IEnumerable <DbModificationClause>)tree.SetClauses)
            {
                if (flag)
                {
                    flag = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept((DbExpressionVisitor)translator);
                commandText.Append(" = ");
                setClause.Value.Accept((DbExpressionVisitor)translator);
            }
            if (flag)
            {
                commandText.Append("[place_holder] ");
            }
            commandText.AppendLine();
            commandText.Append("where ");
            tree.Predicate.Accept((DbExpressionVisitor)translator);
            if (flag)
            {
                string str      = commandText.ToString();
                int    num      = str.IndexOf("where ");
                string newValue = str.Substring(num + "where ".Length).Replace("(", "").Replace(")", "").Replace(" and ", " ,");
                commandText.Replace("[place_holder]", newValue);
            }
            commandText.AppendLine();
            DmlSqlGenerator.GenerateReturningSql(commandText, (DbModificationCommandTree)tree, translator, tree.Returning, providerManifest, sqlVersion, true);
            parameters = translator.Parameters;
            return(commandText.ToString());
        }
Beispiel #26
0
        private static DbCommandTree HandleUpdateCommand(DbUpdateCommandTree updateCommand)
        {
            var now = DateTime.UtcNow;

            var setClauses = updateCommand.SetClauses
                             .Select(clause => clause.UpdateIfMatch(ModifiedColumnName, DbExpression.FromDateTime(now)))
                             .ToList();

            //Removing Created column as it should never be allowed to be modified
            setClauses.RemoveAll(clause => clause.IsFor(CreatedColumnName));

            return(new DbUpdateCommandTree(
                       updateCommand.MetadataWorkspace,
                       updateCommand.DataSpace,
                       updateCommand.Target,
                       updateCommand.Predicate,
                       setClauses.AsReadOnly(), null));
        }
Beispiel #27
0
        public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
        {
            if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
            {
                //This was Rowan Miller's example for filtering out IsDeleteds, but I'm going to try Jimmy Bogard's method instead.
                var queryCommand = interceptionContext.Result as DbQueryCommandTree;
                if (queryCommand != null)
                {
                    var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());
                    interceptionContext.Result = new DbQueryCommandTree(
                        queryCommand.MetadataWorkspace,
                        queryCommand.DataSpace,
                        newQuery);
                }

                var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;
                if (deleteCommand != null)
                {
                    var column = SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType);
                    if (column != null)
                    {
                        var setClause =
                            DbExpressionBuilder.SetClause(
                                DbExpressionBuilder.Property(
                                    DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName),
                                    column),
                                DbExpression.FromBoolean(true));

                        var update = new DbUpdateCommandTree(
                            deleteCommand.MetadataWorkspace,
                            deleteCommand.DataSpace,
                            deleteCommand.Target,
                            deleteCommand.Predicate,
                            new List <DbModificationClause> {
                            setClause
                        }.AsReadOnly(),
                            null);

                        interceptionContext.Result = update;
                    }
                }
            }
        }
Beispiel #28
0
        /// <summary>
        ///     This method is added as a part of the fix for bug 13533
        ///     In this method we try to see from the command tree whether there is any
        ///     updatable column(Property) available on the table(EntityType)
        private static bool GetUpdatableColumn(DbUpdateCommandTree tree, out string updatableColumnName)
        {
            var result = false;

            updatableColumnName = "";
            var entityType = (EntityType)tree.Target.VariableType.EdmType;

            foreach (var edmProperty in entityType.Properties)
            {
                if (entityType.KeyMembers.Contains(edmProperty.Name))
                {
                    // continue if it is a primary key
                    continue;
                }
                if (rowversionString == edmProperty.TypeUsage.EdmType.Name)
                {
                    // if the property is of type rowversion then we continue checking the next item in the list
                    continue;
                }

                // check whether the property is a identity type
                if (edmProperty.TypeUsage.Facets.Contains(storeGeneratedPatternString))
                {
                    var fct = edmProperty.TypeUsage.Facets.GetValue(storeGeneratedPatternString, false);
                    if (StoreGeneratedPattern.Identity
                        == (StoreGeneratedPattern)fct.Value)
                    {
                        // continue to check for the next property if the current property is a identity
                        continue;
                    }
                }
                //if the column is found then return the column name string
                updatableColumnName = edmProperty.Name;
                result = true;
                break;
            }

            return(result);
        }
Beispiel #29
0
        private static DbModificationCommandTree RebuildCommandTree(
            DbModificationCommandTree originalTree,
            Dictionary <DbSetClause, DbSetClause> clauseMappings)
        {
            if (clauseMappings.Count == 0)
            {
                return(originalTree);
            }
            DbModificationCommandTree modificationCommandTree;

            if (originalTree.CommandTreeKind == DbCommandTreeKind.Insert)
            {
                DbInsertCommandTree insertCommandTree = (DbInsertCommandTree)originalTree;
                modificationCommandTree = (DbModificationCommandTree) new DbInsertCommandTree(insertCommandTree.MetadataWorkspace, insertCommandTree.DataSpace, insertCommandTree.Target, new ReadOnlyCollection <DbModificationClause>((IList <DbModificationClause>)DynamicUpdateCommand.ReplaceClauses(insertCommandTree.SetClauses, clauseMappings)), insertCommandTree.Returning);
            }
            else
            {
                DbUpdateCommandTree updateCommandTree = (DbUpdateCommandTree)originalTree;
                modificationCommandTree = (DbModificationCommandTree) new DbUpdateCommandTree(updateCommandTree.MetadataWorkspace, updateCommandTree.DataSpace, updateCommandTree.Target, updateCommandTree.Predicate, new ReadOnlyCollection <DbModificationClause>((IList <DbModificationClause>)DynamicUpdateCommand.ReplaceClauses(updateCommandTree.SetClauses, clauseMappings)), updateCommandTree.Returning);
            }
            return(modificationCommandTree);
        }
Beispiel #30
0
        public override string GenerateSQL(DbCommandTree tree)
        {
            DbUpdateCommandTree commandTree = tree as DbUpdateCommandTree;

            UpdateStatement statement = new UpdateStatement();

            _onReturningSelect = false;
            statement.Target   = commandTree.Target.Expression.Accept(this);
            scope.Add("target", statement.Target as InputFragment);

            if (values == null)
            {
                values = new Dictionary <EdmMember, SqlFragment>();
            }

            foreach (DbSetClause setClause in commandTree.SetClauses)
            {
                statement.Properties.Add(setClause.Property.Accept(this));
                DbExpression value         = setClause.Value;
                SqlFragment  valueFragment = value.Accept(this);
                statement.Values.Add(valueFragment);

                if (value.ExpressionKind != DbExpressionKind.Null)
                {
                    EdmMember property = ((DbPropertyExpression)setClause.Property).Property;
                    values.Add(property, valueFragment);
                }
            }

            statement.Where = commandTree.Predicate.Accept(this);

            _onReturningSelect = true;
            if (commandTree.Returning != null)
            {
                statement.ReturningSelect = GenerateReturningSql(commandTree, commandTree.Returning);
            }

            return(statement.ToString());
        }
Beispiel #31
0
        internal UpdateCommand BuildUpdateCommand(
            PropagatorResult oldRow,
            PropagatorResult newRow,
            TableChangeProcessor processor)
        {
            bool rowMustBeTouched = false;
            DbExpressionBinding         target = UpdateCompiler.GetTarget(processor);
            List <DbModificationClause> modificationClauseList = new List <DbModificationClause>();
            Dictionary <int, string>    outputIdentifiers;
            DbExpression returning;

            foreach (DbModificationClause buildSetClause in this.BuildSetClauses(target, newRow, oldRow, processor, false, out outputIdentifiers, out returning, ref rowMustBeTouched))
            {
                modificationClauseList.Add(buildSetClause);
            }
            DbExpression predicate = this.BuildPredicate(target, oldRow, newRow, processor, ref rowMustBeTouched);

            if (modificationClauseList.Count == 0)
            {
                if (rowMustBeTouched)
                {
                    List <IEntityStateEntry> source = new List <IEntityStateEntry>();
                    source.AddRange((IEnumerable <IEntityStateEntry>)SourceInterpreter.GetAllStateEntries(oldRow, this.m_translator, processor.Table));
                    source.AddRange((IEnumerable <IEntityStateEntry>)SourceInterpreter.GetAllStateEntries(newRow, this.m_translator, processor.Table));
                    if (source.All <IEntityStateEntry>((Func <IEntityStateEntry, bool>)(it => it.State == EntityState.Unchanged)))
                    {
                        rowMustBeTouched = false;
                    }
                }
                if (!rowMustBeTouched)
                {
                    return((UpdateCommand)null);
                }
            }
            DbUpdateCommandTree updateCommandTree = new DbUpdateCommandTree(this.m_translator.MetadataWorkspace, DataSpace.SSpace, target, predicate, new ReadOnlyCollection <DbModificationClause>((IList <DbModificationClause>)modificationClauseList), returning);

            return((UpdateCommand) new DynamicUpdateCommand(processor, this.m_translator, ModificationOperator.Update, oldRow, newRow, (DbModificationCommandTree)updateCommandTree, outputIdentifiers));
        }
 public SqlUpdateGenerator(DbUpdateCommandTree commandTree, NpgsqlProviderManifest providerManifest)
     : base(providerManifest)
 {
     _commandTree = commandTree;
 }
Beispiel #33
0
        internal static string GenerateUpdateSql(
            DbUpdateCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords    = true)
        {
            const string dummySetParameter = "@p";

            var commandText
                = new SqlStringBuilder(CommandTextBuilderInitialCapacity)
                {
                UpperCaseKeywords = upperCaseKeywords
                };

            var translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, sqlGenerator);

            if (tree.SetClauses.Count == 0)
            {
                commandText.AppendKeyword("declare ");
                commandText.AppendLine(dummySetParameter + " int");
            }

            // update [schemaName].[tableName]
            commandText.AppendKeyword("update ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // set c1 = ..., c2 = ..., ...
            var first = true;

            commandText.AppendKeyword("set ");
            foreach (DbSetClause setClause in tree.SetClauses)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept(translator);
                commandText.Append(" = ");
                setClause.Value.Accept(translator);
            }

            if (first)
            {
                // If first is still true, it indicates there were no set
                // clauses. Introduce a fake set clause so that:
                // - we acquire the appropriate locks
                // - server-gen columns (e.g. timestamp) get recomputed
                //
                // We use the following pattern:
                //
                //  update Foo
                //  set @p = 0
                //  where ...
                commandText.Append(dummySetParameter + " = 0");
            }
            commandText.AppendLine();

            // where c1 = ..., c2 = ...
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept(translator);
            commandText.AppendLine();

            if (generateReturningSql)
            {
                GenerateReturningSql(commandText, tree, null, translator, tree.Returning, false);
            }

            parameters = translator.Parameters;

            return(commandText.ToString());
        }
 public UpdateCommandAction(DbUpdateCommandTree commandTree)
 {
     this.commandTree = commandTree;
 }
Beispiel #35
0
 public SqlUpdateGenerator(DbUpdateCommandTree commandTree)
 {
     _commandTree = commandTree;
 }