/// <summary> /// Gets the table alias. /// </summary> /// <param name="process">The process.</param> /// <returns>System.String.</returns> public string GetTableAlias(ProcessDefinition process) { if (!_tableAliases.ContainsKey(process)) _tableAliases[process] = "t" + _tableAliasIndex++; return _tableAliases[process]; }
/// <summary> /// Creates the process definition. /// </summary> /// <param name="process">The process.</param> /// <returns>ProcessDefinition.</returns> private ProcessDefinition CreateProcessDefinition(PublishedProcessInfo process) { var processDefinition = new ProcessDefinition { SystemName = process.SystemName }; if (process.BaseProcess != null) processDefinition.BaseProcess = CreateProcessDefinition(process.BaseProcess); return processDefinition; }
/// <summary> /// Finds the base process. /// </summary> /// <param name="process">The process.</param> /// <param name="processName">Name of the process.</param> /// <returns>ProcessDefinition.</returns> private ProcessDefinition FindBaseProcess(ProcessDefinition process, string processName) { var currentProcess = process; while (currentProcess != null && currentProcess.SystemName != processName) currentProcess = currentProcess.BaseProcess; return currentProcess; }
/// <summary> /// Creates the join from system field. /// </summary> /// <param name="process">The process.</param> /// <param name="fieldName">Name of the field.</param> /// <returns>ReferenceFieldDefinition.</returns> /// <exception cref="System.InvalidOperationException"></exception> private ReferenceFieldDefinition CreateJoinFromSystemField(ProcessDefinition process, string fieldName) { switch (fieldName) { case Constants.CurrentStateColumnName: { var stateProcess = GetPublishedProcessInfo(Constants.StateProcessName); return new SingleCrossReferenceFieldDefinition { SystemName = Constants.CurrentStateColumnName, DeclaringProcess = process, ReferencedProcess = CreateProcessDefinition(stateProcess) }; } case Constants.PaperclipsColumnName: { var paperclipProcess = GetPublishedProcessInfo(Constants.PaperclipProcessName); return new MultiCrossReferenceFieldDefinition { SystemName = Constants.PaperclipsColumnName, DeclaringProcess = process, ReferencedProcess = CreateProcessDefinition(paperclipProcess) }; } } throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", fieldName)); }
/// <summary> /// Creates the process definition. /// </summary> /// <param name="process">The process.</param> /// <returns>ProcessDefinition.</returns> private ProcessDefinition CreateProcessDefinition(IProcessEdit process) { var processDefinition = new ProcessDefinition { SystemName = process.SystemName }; if (process.BaseProcess != null) processDefinition.BaseProcess = CreateProcessDefinition(process.BaseProcess); return processDefinition; }
/// <summary> /// Creates the join. /// </summary> /// <param name="process">The process.</param> /// <param name="field">The field.</param> /// <returns>ReferenceFieldDefinition.</returns> /// <exception cref="System.InvalidOperationException"> /// </exception> private ReferenceFieldDefinition CreateJoin(ProcessDefinition process, FieldEdit field) { var declaringProcess = FindBaseProcess(process, field.GetBaseCopy().GetParent<IProcessEdit>().SystemName); switch (field.GetColumnType()) { case ColumnTypes.Reference: { var step = field.StepList.OfType<CrossRefRequiredStepEdit>().FirstOrDefault(); if (step == null || !step.CrossRefProcessId.HasValue) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = GetPublishedProcessInfo(step.CrossRefProcessId.Value); var join = new SingleCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = CreateProcessDefinition(referencedProcess) }; return join; } case ColumnTypes.MultiReference: { var step = field.StepList.OfType<CrossRefRequiredStepEdit>().FirstOrDefault(); if (step == null || !step.CrossRefProcessId.HasValue) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = GetPublishedProcessInfo(step.CrossRefProcessId.Value); var join = new MultiCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = CreateProcessDefinition(referencedProcess) }; if (!string.IsNullOrEmpty(step.LinkFieldSystemName)) join.LinkField = (SingleCrossReferenceFieldDefinition)CreateJoin(join.ReferencedProcess, step.LinkFieldSystemName); return join; } case ColumnTypes.ReverseReference: { var step = field.StepList.OfType<ReverseCrossRefRequiredStepEdit>().FirstOrDefault(); if (step == null || !step.ReverseCrossRefProcessId.HasValue) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var optionsStep = field.StepList.OfType<ReverseCrossRefOptionsStepEdit>().FirstOrDefault(); var referencedProcess = CreateProcessDefinition(GetPublishedProcessInfo(step.ReverseCrossRefProcessId.Value)); var join = new SingleReverseCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = referencedProcess, ReferenceField = CreateJoin(referencedProcess, step.CrossRefFieldName), ShowLatestVersion = optionsStep != null && optionsStep.ShowLatestVersion }; return join; } case ColumnTypes.ReverseMultiReference: { var step = field.StepList.OfType<ReverseCrossRefRequiredStepEdit>().FirstOrDefault(); if (step == null || !step.ReverseCrossRefProcessId.HasValue) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var optionsStep = field.StepList.OfType<ReverseCrossRefOptionsStepEdit>().FirstOrDefault(); var referencedProcess = CreateProcessDefinition(GetPublishedProcessInfo(step.ReverseCrossRefProcessId.Value)); var join = new MultiReverseCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = referencedProcess, ReferenceField = CreateJoin(referencedProcess, step.CrossRefFieldName), ShowLatestVersion = optionsStep != null && optionsStep.ShowLatestVersion }; return join; } case ColumnTypes.Checklist: { var step = field.StepList.OfType<ChecklistSettingsStepEdit>().FirstOrDefault(); if (step == null || string.IsNullOrEmpty(step.AnswerProcessSystemName)) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = GetPublishedProcessInfo(step.AnswerProcessSystemName); var join = new ChecklistFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = CreateProcessDefinition(referencedProcess) }; return join; } } throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); }
/// <summary> /// Creates the join. /// </summary> /// <param name="process">The process.</param> /// <param name="field">The field.</param> /// <returns>ReferenceFieldDefinition.</returns> /// <exception cref="System.InvalidOperationException"> /// </exception> private ReferenceFieldDefinition CreateJoin(ProcessDefinition process, Process.FieldInfo field) { var declaringProcess = FindBaseProcess(process, field.DefinedIn); switch (field.ColumnType) { case ColumnTypes.Reference: { var fieldInfo = CrossRefFieldInfo.GetCrossRefFieldInfo(field.Id); if (fieldInfo == null || fieldInfo.CrossRefProcessId == 0) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = GetPublishedProcessInfo(fieldInfo.CrossRefProcessId); var join = new SingleCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = CreateProcessDefinition(referencedProcess) }; return join; } case ColumnTypes.MultiReference: { var fieldInfo = CrossRefFieldInfo.GetCrossRefFieldInfo(field.Id); if (fieldInfo == null || fieldInfo.CrossRefProcessId == 0) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = CreateProcessDefinition(GetPublishedProcessInfo(fieldInfo.CrossRefProcessId)); var join = new MultiCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = referencedProcess }; if (!string.IsNullOrEmpty(fieldInfo.LinkFieldSystemName)) join.LinkField = (SingleCrossReferenceFieldDefinition)CreateJoin(referencedProcess, fieldInfo.LinkFieldSystemName); return join; } case ColumnTypes.ReverseReference: { var fieldInfo = ReverseCrossRefFieldInfo.GetReverseCrossRefFieldInfo(field.Id); if (fieldInfo == null || fieldInfo.ReferenceProcessId == 0) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = CreateProcessDefinition(GetPublishedProcessInfo(fieldInfo.ReferenceProcessId)); var join = new SingleReverseCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = referencedProcess, ReferenceField = CreateJoin(referencedProcess, fieldInfo.ReferenceField), ShowLatestVersion = fieldInfo.ShowLatestVersion }; return join; } case ColumnTypes.ReverseMultiReference: { var fieldInfo = ReverseCrossRefFieldInfo.GetReverseCrossRefFieldInfo(field.Id); if (fieldInfo == null || fieldInfo.ReferenceProcessId == 0) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = CreateProcessDefinition(GetPublishedProcessInfo(fieldInfo.ReferenceProcessId)); var join = new MultiReverseCrossReferenceFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = referencedProcess, ReferenceField = CreateJoin(referencedProcess, fieldInfo.ReferenceField), ShowLatestVersion = fieldInfo.ShowLatestVersion }; return join; } case ColumnTypes.Checklist: { var fieldInfo = ChecklistFieldInfo.GetChecklistFieldInfo(field.Id); if (fieldInfo == null || fieldInfo.CrossRefProcessId == 0) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); var referencedProcess = GetPublishedProcessInfo(fieldInfo.CrossRefProcessId); var join = new ChecklistFieldDefinition { SystemName = field.SystemName, DeclaringProcess = declaringProcess, ReferencedProcess = CreateProcessDefinition(referencedProcess) }; return join; } } throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Field \"{0}\" is not a valid reference field.", field.SystemName)); }
/// <summary> /// Creates the join. /// </summary> /// <param name="process">The process.</param> /// <param name="fieldName">Name of the field.</param> /// <returns>ReferenceFieldDefinition.</returns> /// <exception cref="VeyronException"></exception> private ReferenceFieldDefinition CreateJoin(ProcessDefinition process, string fieldName) { if (IsSystemField(fieldName)) return CreateJoinFromSystemField(process, fieldName); var processFields = FieldList.GetFieldList(process.SystemName); var field = processFields.FirstOrDefault(f => f.SystemName == fieldName); if (field == null) throw new VeyronException(string.Format("Could not find field \"{0}\" in process \"{1}\".", fieldName, process.SystemName)); return CreateJoin(process, field); }
/// <summary> /// Creates the dependencies from system field. /// </summary> /// <param name="process">The process.</param> /// <param name="fieldName">Name of the field.</param> /// <returns>IEnumerable{ExpressionDependency}.</returns> private IEnumerable<ExpressionDependency> CreateDependenciesFromSystemField(ProcessDefinition process, string fieldName) { yield return new ExpressionDependency { ProcessName = process.SystemName, FieldName = fieldName }; }
/// <summary> /// Creates the dependencies. /// </summary> /// <param name="process">The process.</param> /// <param name="field">The field.</param> /// <returns>IEnumerable{ExpressionDependency}.</returns> private IEnumerable<ExpressionDependency> CreateDependencies(ProcessDefinition process, Process.FieldInfo field) { switch (field.ColumnType) { case ColumnTypes.ReverseReference: case ColumnTypes.ReverseMultiReference: { var join = (ReverseCrossReferenceFieldDefinition)CreateJoin(process, field); foreach (var dependency in CreateDependencies(join.ReferencedProcess, join.ReferenceField.SystemName)) { dependency.JoinFields.Insert(0, join); yield return dependency; } } yield break; case ColumnTypes.MultiReference: { var join = (MultiCrossReferenceFieldDefinition)CreateJoin(process, field); if (join.LinkField == null) { yield return new ExpressionDependency { ProcessName = join.DeclaringProcess.SystemName, FieldName = join.SystemName }; } else { foreach (var dependency in CreateDependencies(join.ReferencedProcess, join.LinkField.SystemName)) { dependency.JoinFields.Insert(0, join); yield return dependency; } } } yield break; case ColumnTypes.DisplayList: // Since we can't determine which items should recalculate expressions when a DL item changes // and recalculating expressions for all items is too slow, we'll skip DL dependencies. yield break; default: { yield return new ExpressionDependency { ProcessName = field.DefinedIn, FieldName = field.SystemName }; } yield break; } }
/// <summary> /// Creates the dependencies. /// </summary> /// <param name="process">The process.</param> /// <param name="fullPath">The full path.</param> /// <returns>IEnumerable{ExpressionDependency}.</returns> /// <exception cref="System.ArgumentException">Invalid property path.;fullPath</exception> /// <exception cref="System.InvalidOperationException"></exception> private IEnumerable<ExpressionDependency> CreateDependencies(ProcessDefinition process, string fullPath) { var tokens = fullPath.Split(new[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length == 0) throw new ArgumentException("Invalid property path.", "fullPath"); if (IsSystemField(tokens[0])) { if (tokens.Length > 1) { var join = CreateJoinFromSystemField(process, tokens[0]); foreach (var dependency in CreateDependencies(join.ReferencedProcess, tokens[1])) { dependency.JoinFields.Insert(0, join); yield return dependency; } yield break; } foreach (var dependency in CreateDependenciesFromSystemField(process, tokens[0])) yield return dependency; yield break; } var processFields = FieldList.GetFieldList(process.SystemName); var field = processFields.FirstOrDefault(f => f.SystemName == tokens[0]); if (field == null) throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Could not find field \"{0}\" in process \"{1}\".", tokens[0], process.SystemName)); if (field.ColumnType == ColumnTypes.DisplayList) { // Since we can't determine which items should recalculate expressions when a DL item changes // and recalculating expressions for all items is too slow, we'll skip DL dependencies. yield break; } if (tokens.Length > 1 && IsJoinField(field)) { var join = CreateJoin(process, field); foreach (var dependency in CreateDependencies(join.ReferencedProcess, tokens[1])) { dependency.JoinFields.Insert(0, join); yield return dependency; } yield break; } foreach (var dependency in CreateDependencies(process, field)) yield return dependency; }
private static void AddBaseTableJoins( StringBuilder sql, ProcessDefinition process, ProcessDefinition lastProcess, TableAliasCollection aliasCollection) { if (process == lastProcess || process.BaseProcess == null) return; sql.AppendLine() .Append("\t") .AppendFormat( @"INNER JOIN [dbo].[{0}] {1} ON {1}.[{2}] = {3}.[{4}]", process.BaseProcess.SystemName, aliasCollection.GetTableAlias(process.BaseProcess), Constants.IdColumnName, aliasCollection.GetTableAlias(process), Constants.BaseIdColumnName); AddBaseTableJoins(sql, process.BaseProcess, lastProcess, aliasCollection); }