private static bool CheckNode([NotNull] ConstraintNode constraintNode) { TableView tableView = constraintNode.Helper; bool caseSensitive = tableView.CaseSensitive; var resetCaseSensitivity = false; if (constraintNode.CaseSensitivityOverride != null) { tableView.CaseSensitive = constraintNode.CaseSensitivityOverride.Value; resetCaseSensitivity = true; } try { return(tableView.FilteredRowCount == 1); } finally { if (resetCaseSensitivity) { tableView.CaseSensitive = caseSensitive; } } }
/// <summary> /// Initializes a new instance of the <see cref="SnapshotElementComparer" /> class. /// </summary> /// <param name="region">The parent region that contains this element.</param> /// <param name="pointerIncrementMode">The method by which to increment element pointers.</param> /// <param name="constraints">The constraints to use for the element comparisons.</param> public unsafe SnapshotElementComparer( SnapshotRegion region, PointerIncrementMode pointerIncrementMode, ConstraintNode constraints) : this(region, pointerIncrementMode) { this.ElementCompare = this.BuildCompareActions(constraints); }
/// <summary> /// Starts the scan using the current constraints. /// </summary> private void StartScan() { // Create a constraint manager that includes the current active constraint ConstraintNode scanConstraints = this.ActiveConstraint.Clone(); if (!scanConstraints.IsValid()) { Logger.Log(LogLevel.Warn, "Unable to start scan with given constraints"); return; } DataType dataType = ScanResultsViewModel.GetInstance().ActiveType; // Collect values TrackableTask <Snapshot> valueCollectorTask = ValueCollector.CollectValues( SnapshotManager.GetSnapshot(Snapshot.SnapshotRetrievalMode.FromActiveSnapshotOrPrefilter, dataType)); TaskTrackerViewModel.GetInstance().TrackTask(valueCollectorTask); // Perform manual scan on value collection complete valueCollectorTask.OnCompletedEvent += ((completedValueCollection) => { Snapshot snapshot = valueCollectorTask.Result; TrackableTask <Snapshot> scanTask = ManualScanner.Scan( snapshot, scanConstraints); TaskTrackerViewModel.GetInstance().TrackTask(scanTask); SnapshotManager.SaveSnapshot(scanTask.Result); }); }
/// <summary> /// Updates the active type. /// </summary> /// <param name="activeType">The new active type.</param> public void Update(DataType activeType) { // Create a temporary manager to update our current constraint ConstraintNode scanConstraintCollection = new ConstraintNode(); // scanConstraintCollection.AddConstraint(this.CurrentScanConstraint); scanConstraintCollection.SetElementType(activeType); this.ActiveConstraint.SetElementType(activeType); this.UpdateAllProperties(); }
/// <summary> /// Gets the enumerator for an element reference within this snapshot region. /// </summary> /// <param name="pointerIncrementMode">The method for incrementing pointers.</param> /// <param name="compareActionConstraint">The constraint to use for the element quick action.</param> /// <param name="compareActionValue">The value to use for the element quick action.</param> /// <returns>The enumerator for an element reference within this snapshot region.</returns> public IEnumerator <SnapshotElementComparer> IterateComparer( SnapshotElementComparer.PointerIncrementMode pointerIncrementMode, ConstraintNode constraints) { Int32 elementCount = this.ElementCount; SnapshotElementComparer snapshotElement = new SnapshotElementComparer(region: this, pointerIncrementMode: pointerIncrementMode, constraints: constraints); for (Int32 elementIndex = 0; elementIndex < elementCount; elementIndex++) { yield return(snapshotElement); snapshotElement.IncrementPointers(); } }
private bool TryParseTargetConstraint(out ConstraintNode <Target> constraint) { switch (_scanner.Token) { case IdToken _: constraint = ParseIdConstraint <Target>(); return(true); case NameToken _: constraint = ParseNameConstraint <Target>(); return(true); default: constraint = null; return(false); } ; }
public static IList <ConstraintNode> GetConstraintHierarchy( [NotNull] IList <string> constraints) { Assert.ArgumentNotNull(constraints, nameof(constraints)); var constraintNodes = new List <ConstraintNode>(); var nodeHierarchy = new List <IList <ConstraintNode> > { constraintNodes }; foreach (string constraint in constraints) { string trimmedConstraint = constraint.Trim(); int nPlus = 0; while (trimmedConstraint.StartsWith("+")) { trimmedConstraint = trimmedConstraint.Substring(1).Trim(); nPlus++; } while (nodeHierarchy.Count > nPlus + 1) { nodeHierarchy.RemoveAt(nPlus + 1); } var node = new ConstraintNode(trimmedConstraint); Assert.True(nodeHierarchy.Count == nPlus + 1, "Too many '+' in constraint " + constraint); nodeHierarchy[nPlus].Add(node); nodeHierarchy.Add(node.Nodes); } return(constraintNodes); }
private ConstraintNode GetConstraint([CanBeNull] IList <Code> allowedCodes) { string condition; if (allowedCodes == null || allowedCodes.Count == 0) { condition = null; } else if (allowedCodes.Count == 1) { Code code = allowedCodes[0]; if (code.IsNull) { condition = string.Format("ISNULL({0},{1}) = {1}", code.Field, code.CodeIdString()); } else if (code.CodeName == GeneralConstraintColumnName) { condition = string.Format("ISNULL({0},{1}) <> {1}", code.Field, code.CodeIdString()); } else { condition = string.Format("{0} = {1}", code.Field, code.CodeIdString()); } } else { condition = GetGeneralCondition(allowedCodes); if (condition == null) { var sb = new StringBuilder(); string field = allowedCodes[0].Field; string existing = null; Code nullCode = null; foreach (Code code in allowedCodes) { if (code.CodeName == GeneralConstraintColumnName) { Assert.False(true, "Unhandled general code"); } if (code.IsNull == false) { if (sb.Length > 0) { sb.Append(","); } existing = code.CodeIdString(); sb.Append(existing); } else { nullCode = code; } } if (nullCode == null) { condition = string.Format("{0} IN ({1})", field, sb); } else { condition = string.Format("ISNULL({0},{1}) IN ({2})", field, existing, sb); } } } ConstraintNode node = condition != null ? new ConstraintNode(condition) : null; return(node); }
private void AppendConstraintNode(ConstraintNode node, Dictionary <string, FieldValues> fieldNames, StringBuilder csvBuilder, ref string generalCondition, Dictionary <string, IList <int> > domainConditions) { string condition = node.Condition; if (node.Nodes.Count == 0) { AddCondition(csvBuilder, null, null, condition, fieldNames, ref generalCondition, domainConditions); } else { string field = null; string code = null; IList <string> terms = Parse(condition); if (terms.Count == 3 && terms[1] == "=") { FieldValues fieldValues; if (TryGetSubtype(terms, out code)) { field = _subtypeField; } if (field == null && fieldNames.TryGetValue(terms[0].ToUpper(), out fieldValues)) { int idx = fieldValues.IndexOfCodeValueString(terms[2].Trim('\'')); if (idx >= 0) { field = fieldValues.Name; code = fieldValues.CodeNames[idx]; } } } if (field == null) { field = condition; code = null; } string codeGenerellCondition = null; var codeDomainConditions = new Dictionary <string, IList <int> >(); foreach (ConstraintNode codeNode in node.Nodes) { AddCondition(csvBuilder, field, code, codeNode.Condition, fieldNames, ref codeGenerellCondition, codeDomainConditions); } AppendConditions(csvBuilder, field, code, ref codeGenerellCondition, codeDomainConditions, fieldNames); } }
protected void CreateCore([NotNull] TextReader reader, [NotNull] IEnumerable <Dataset> datasets) { Assert.ArgumentNotNull(reader, nameof(reader)); Assert.ArgumentNotNull(datasets, nameof(datasets)); string attributesLine = reader.ReadLine(); Assert.NotNull(attributesLine, "attributesLine"); string[] attributesStrings = attributesLine.Split(';'); string conditionLine = reader.ReadLine(); Assert.NotNull(conditionLine, "conditionLine"); string[] conditionStrings = conditionLine.Split(';'); string datasetName = attributesStrings[0]; Dataset = Assert.NotNull( ConfiguratorUtils.GetDataset <ObjectDataset>(datasetName, datasets), "Dataset {0} not found", datasetName); IObjectClass objectClass = ConfiguratorUtils.OpenFromDefaultDatabase(Dataset); Assert.True(string.IsNullOrEmpty(attributesStrings[1]), "Invalid Matrix Format"); Assert.True(string.IsNullOrEmpty(attributesStrings[2]) || attributesStrings[2].Equals(GeneralConstraintColumnName, StringComparison.InvariantCultureIgnoreCase), "Invalid Matrix Format"); Assert.True(string.IsNullOrEmpty(conditionStrings[0]), "Invalid Matrix Header Format: expected '', got '{0}'", conditionStrings[0]); Assert.True(string.IsNullOrEmpty(conditionStrings[1]), "Invalid Matrix Header Format: expected '', got '{0}'", conditionStrings[1]); Assert.True(string.IsNullOrEmpty(conditionStrings[2]), "Invalid Matrix Header Format: expected '', got '{0}'", conditionStrings[0]); //if (fieldName == null) //{ // fieldName = ((ISubtypes)table).SubtypeFieldName; //} //int fieldIdx = table.FindField(fieldName); //IField field = table.Fields.get_Field(fieldIdx); IList <Code> possibleCodes = GetCodes(attributesStrings, conditionStrings, objectClass); int n = possibleCodes.Count; string attr0 = null; SortedDictionary <string, object> codeValues = null; var allConstraints = new List <ConstraintNode>(); for (string codeLine = reader.ReadLine(); codeLine != null; codeLine = reader.ReadLine()) { IList <string> codes = codeLine.Split(';'); string attr = codes[0]; string code = codes[1]; var rowConstraints = new List <ConstraintNode>(); string generelConstraint = codes[2]; if (string.IsNullOrEmpty(generelConstraint) == false) { rowConstraints.Add(new ConstraintNode(generelConstraint)); } var allowedCodes = new List <Code>(); for (var i = 0; i < n; i++) { string value = codes[i + 3].Trim(); if (possibleCodes[i] == null) { Assert.True(string.IsNullOrEmpty(value), "Unhandled value {0} for empty Code", value); } else if (value == "1") { allowedCodes.Add(possibleCodes[i]); } else if (value == "0") { } else { Assert.True(false, "Unhandled value {0}", value); } } allowedCodes.Sort(Code.SortField); string field0 = null; List <Code> fieldCodes = null; foreach (Code allowedCode in allowedCodes) { if (allowedCode.Field.Equals(field0, StringComparison.InvariantCultureIgnoreCase) == false) { if (fieldCodes != null) { ConstraintNode node = GetConstraint(fieldCodes); if (node != null) { rowConstraints.Add(node); } } fieldCodes = new List <Code>(); field0 = allowedCode.Field; } Assert.NotNull(fieldCodes, "fieldCodes is null"); fieldCodes.Add(allowedCode); } if (fieldCodes != null) { rowConstraints.Add(GetConstraint(fieldCodes)); } if (string.IsNullOrEmpty(code)) { if (string.IsNullOrEmpty(attr)) { allConstraints.AddRange(rowConstraints); } else { var constraintConstraint = new ConstraintNode(attr); foreach (ConstraintNode constraint in allConstraints) { constraintConstraint.Nodes.Add(constraint); } } } else { if (!string.IsNullOrEmpty(attr) && !attr.Equals(attr0, StringComparison.InvariantCultureIgnoreCase)) { codeValues = GetCodeValues(attr, objectClass); attr0 = attr; } Assert.NotNull(codeValues, "No coded value field defined"); code = AdaptCode(attr0, code, codeValues); Code lineCode = code != _nullValue ? new Code(attr0, code, codeValues[code]) : new Code(attr0, codeValues[_nullValue]); string constraint = string.Format("{0} = {1}", attr0, lineCode.CodeIdString()); var codeConstraint = new ConstraintNode(constraint); foreach (ConstraintNode node in rowConstraints) { codeConstraint.Nodes.Add(node); } allConstraints.Add(codeConstraint); } } Constraints = allConstraints; }
/// <summary> /// Initializes a new instance of the <see cref="SnapshotElementVectorComparer" /> class. /// </summary> /// <param name="region">The parent region that contains this element.</param> /// <param name="constraints">The set of constraints to use for the element comparisons.</param> public SnapshotElementVectorComparer(SnapshotRegion region, ConstraintNode constraints) : this(region) { this.VectorCompare = this.BuildCompareActions(constraints); }
/// <summary> /// Begins the manual scan based on the provided snapshot and parameters. /// </summary> /// <param name="snapshot">The snapshot on which to perfrom the scan.</param> /// <param name="constraints">The collection of scan constraints to use in the manual scan.</param> /// <param name="taskIdentifier">The unique identifier to prevent duplicate tasks.</param> /// <returns></returns> public static TrackableTask <Snapshot> Scan(Snapshot snapshot, ConstraintNode constraints, String taskIdentifier = null) { try { return(TrackableTask <Snapshot> .Create(ManualScanner.Name, taskIdentifier, out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task <Snapshot> .Run(() => { Snapshot result = null; try { cancellationToken.ThrowIfCancellationRequested(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Int32 processedPages = 0; ConcurrentBag <IList <SnapshotRegion> > regions = new ConcurrentBag <IList <SnapshotRegion> >(); ParallelOptions options = ParallelSettings.ParallelSettingsFastest.Clone(); options.CancellationToken = cancellationToken; Parallel.ForEach( snapshot.OptimizedSnapshotRegions, options, (region) => { // Check for canceled scan cancellationToken.ThrowIfCancellationRequested(); if (!region.ReadGroup.CanCompare(constraints.HasRelativeConstraint())) { return; } SnapshotElementVectorComparer vectorComparer = new SnapshotElementVectorComparer(region: region, constraints: constraints); IList <SnapshotRegion> results = vectorComparer.Compare(); if (!results.IsNullOrEmpty()) { regions.Add(results); } // Update progress every N regions if (Interlocked.Increment(ref processedPages) % 32 == 0) { updateProgress((float)processedPages / (float)snapshot.RegionCount * 100.0f); } }); //// End foreach Region // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); result = new Snapshot(ManualScanner.Name, regions.SelectMany(region => region)); stopwatch.Stop(); Logger.Log(LogLevel.Info, "Scan complete in: " + stopwatch.Elapsed); } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Scan canceled", ex); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing scan", ex); } return result; }, cancellationToken))); } catch (TaskConflictException ex) { Logger.Log(LogLevel.Warn, "Unable to start scan. Scan is already queued."); throw ex; } }
private float[] GetSplatWeights(int x, int y, int[,] biomeMap, int resolution) { float[] weights = new float[Splats.Length]; Vector2 norm = new Vector2(x / (float)resolution, y / (float)resolution); Vector2 world = MathUtil.NormalToWorld(_tile.GridPosition, norm); int splatOffset = 0; float height = _angleHeightResults.Heights[x, y]; float angle = _angleHeightResults.Angles[x, y]; for (int z = 0; z < Biomes.Length; z++) { SplatDetailNode[] splats = Biomes[z].GetSplatInputs(); if (splats == null) { continue; } float[] splatsWeights = new float[splats.Length]; float curMax = 1f; float oldMax = 1f; float sum = 0f; for (var i = 0; i < splats.Length; i++) { //If no constraint, display SplatDetailNode splat = splats[i]; ConstraintNode cons = splat.GetConstraintValue(); if (cons == null) { splatsWeights[i] = biomeMap[x, y] == z ? 1f : 0f; continue; } //Check whether this SplatData fits required height and angle constraints bool passHeight = cons.ConstrainHeight && cons.HeightConstraint.Fits(height) || !cons.ConstrainHeight; bool passAngle = cons.ConstrainAngle && cons.AngleConstraint.Fits(angle) || !cons.ConstrainAngle; if (!passHeight && !passAngle || !splat.ShouldPlaceAt(world.x, world.y, height, angle)) { continue; } //If it passes height or angle constraints what are the texturing weights float weight = 0; int count = 0; if (passHeight && !passAngle) { weight += cons.HeightConstraint.Weight(height, splat.Blend); count++; } if (passAngle) { weight += cons.AngleConstraint.Weight(angle, splat.Blend); count++; } splatsWeights[i] = weight / count; } // for (int i = 0; i < splats.Length; i++) { // float val = splatsWeights[i]; // float remapped = MathUtil.Map(val, 0f, oldMax, 0f, curMax); // // if (sum >= 1f) { // //No remaining weight to assign, terminate // break; // } // if (i == splats.Length - 1) { // //All remaining weight goes to last idx // splatsWeights[i] = 1 - sum; // break; // } // // sum += remapped; // splatsWeights[i] = remapped; // oldMax = curMax; // curMax = 1 - remapped; // } for (int i = 0; i < splatsWeights.Length; i++) { weights[i + splatOffset] = splatsWeights[i]; } splatOffset += splats.Length; } return(weights); }
/// <summary> /// Sets the default compare action to use for this element. /// </summary> /// <param name="constraints">The constraints to use for the element quick action.</param> private Func <Boolean> BuildCompareActions(ConstraintNode constraints) { if (constraints is Operation) { if (constraints.Left == null || constraints.Right == null) { throw new ArgumentException("An operation constraint must have both a left and right child"); } switch ((constraints as Operation).BinaryOperation) { case Operation.OperationType.AND: return(() => this.BuildCompareActions(constraints.Left).Invoke() && this.BuildCompareActions(constraints.Right).Invoke()); case Operation.OperationType.OR: return(() => this.BuildCompareActions(constraints.Left).Invoke() || this.BuildCompareActions(constraints.Right).Invoke()); default: throw new ArgumentException("Unkown operation type"); } } else if (constraints is ScanConstraint) { ScanConstraint scanConstraint = (constraints as ScanConstraint); switch (scanConstraint.Constraint) { case ScanConstraint.ConstraintType.Unchanged: return(this.Unchanged); case ScanConstraint.ConstraintType.Changed: return(this.Changed); case ScanConstraint.ConstraintType.Increased: return(this.Increased); case ScanConstraint.ConstraintType.Decreased: return(this.Decreased); case ScanConstraint.ConstraintType.IncreasedByX: return(() => this.IncreasedByValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.DecreasedByX: return(() => this.DecreasedByValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.Equal: return(() => this.EqualToValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.NotEqual: return(() => this.NotEqualToValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.GreaterThan: return(() => this.GreaterThanValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.GreaterThanOrEqual: return(() => this.GreaterThanOrEqualToValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.LessThan: return(() => this.LessThanValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.LessThanOrEqual: return(() => this.LessThanOrEqualToValue(scanConstraint.ConstraintValue)); default: throw new Exception("Unknown constraint type"); } } throw new ArgumentException("Invalid constraint node"); }
public override void OnBodyGUI() { //Output / Mask Input NodeEditorGUILayout.PropertyField(serializedObject.FindProperty("Output")); NodeEditorGUILayout.PropertyField(serializedObject.FindProperty("Mask")); EditorGUI.BeginChangeCheck(); if (Constraint.GetMaskValue() != null) { Constraint.Tolerance = EditorGUIExtension.MinMaxFloatField("Tolerance", Constraint.Tolerance, 0f, 1f); } //Height Constraint ConstraintNode cons = Constraint; cons.ConstrainHeight = EditorGUILayout.Toggle("Height", cons.ConstrainHeight); if (cons.ConstrainHeight) { EditorGUI.indentLevel = 1; cons.HeightConstraint = EditorGUIExtension.DrawConstraintRange("Height", cons.HeightConstraint, 0, 1); EditorGUILayout.BeginHorizontal(); cons.HeightProbCurve = EditorGUILayout.CurveField("Probability", cons.HeightProbCurve, Color.green, new Rect(0, 0, 1, 1)); if (GUILayout.Button("?", GUILayout.Width(25))) { const string msg = "This is the height probability curve. The X axis represents the " + "min to max height and the Y axis represents the probability an " + "object will spawn. By default, the curve is set to a 100% probability " + "meaning all objects will spawn."; EditorUtility.DisplayDialog("Help - Height Probability", msg, "Close"); } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 0; } //Angle Constraint cons.ConstrainAngle = EditorGUILayout.Toggle("Angle", cons.ConstrainAngle); if (cons.ConstrainAngle) { EditorGUI.indentLevel = 1; cons.AngleConstraint = EditorGUIExtension.DrawConstraintRange("Angle", cons.AngleConstraint, 0, 1, 90); EditorGUILayout.BeginHorizontal(); cons.AngleProbCurve = EditorGUILayout.CurveField("Probability", cons.AngleProbCurve, Color.green, new Rect(0, 0, 1, 1)); if (GUILayout.Button("?", GUILayout.Width(25))) { const string msg = "This is the angle probability curve. The X axis represents " + "0 to 90 degrees and the Y axis represents the probability an " + "object will spawn. By default, the curve is set to a 100% probability " + "meaning all objects will spawn."; EditorUtility.DisplayDialog("Help - Angle Probability", msg, "Close"); } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 0; } Constraint.PlacementProbability = EditorGUIExtension.MinMaxIntField("Place Prob.", Constraint.PlacementProbability, 0, 100); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); } }
/// <summary> /// Sets the default compare action to use for this element. /// </summary> /// <param name="constraints">The constraints to use for the scan.</param> /// <param name="compareActionValue">The value to use for the scan.</param> private Func <Vector <Byte> > BuildCompareActions(ConstraintNode constraints) { if (constraints is Operation) { if (constraints.Left == null || constraints.Right == null) { throw new ArgumentException("An operation constraint must have both a left and right child"); } switch ((constraints as Operation).BinaryOperation) { case Operation.OperationType.AND: return(() => { Vector <Byte> resultLeft = this.BuildCompareActions(constraints.Left).Invoke(); // Early exit mechanism to prevent extra comparisons if (resultLeft.Equals(Vector <Byte> .Zero)) { return Vector <Byte> .Zero; } Vector <Byte> resultRight = this.BuildCompareActions(constraints.Right).Invoke(); return Vector.BitwiseAnd(resultLeft, resultRight); }); case Operation.OperationType.OR: return(() => { Vector <Byte> resultLeft = this.BuildCompareActions(constraints.Left).Invoke(); // Early exit mechanism to prevent extra comparisons if (resultLeft.Equals(Vector <Byte> .One)) { return Vector <Byte> .One; } Vector <Byte> resultRight = this.BuildCompareActions(constraints.Right).Invoke(); return Vector.BitwiseOr(resultLeft, resultRight); }); default: throw new ArgumentException("Unkown operation type"); } } else if (constraints is ScanConstraint) { ScanConstraint scanConstraint = (constraints as ScanConstraint); switch (scanConstraint.Constraint) { case ScanConstraint.ConstraintType.Unchanged: return(this.Unchanged); case ScanConstraint.ConstraintType.Changed: return(this.Changed); case ScanConstraint.ConstraintType.Increased: return(this.Increased); case ScanConstraint.ConstraintType.Decreased: return(this.Decreased); case ScanConstraint.ConstraintType.IncreasedByX: return(() => this.IncreasedByValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.DecreasedByX: return(() => this.DecreasedByValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.Equal: return(() => this.EqualToValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.NotEqual: return(() => this.NotEqualToValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.GreaterThan: return(() => this.GreaterThanValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.GreaterThanOrEqual: return(() => this.GreaterThanOrEqualToValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.LessThan: return(() => this.LessThanValue(scanConstraint.ConstraintValue)); case ScanConstraint.ConstraintType.LessThanOrEqual: return(() => this.LessThanOrEqualToValue(scanConstraint.ConstraintValue)); default: throw new Exception("Unknown constraint type"); } } throw new ArgumentException("Invalid constraint node"); }
public void AddConstraint(ConstraintNode constraint) { Constraints.Add(constraint); }
public void CanOverrideCaseSensitivityForComplexCondition() { const string textFieldName = "TextField"; const string value = "aaa"; int textFieldIndex; ObjectClassMock objectClass = CreateObjectClass(textFieldName, out textFieldIndex); string ignoreCaseOverride = string.Format("{0} = '{1}'##IGNORECASE", textFieldName, value.ToUpper()); string caseSensitiveOverride = string.Format("{0} = '{1}'##CASESENSITIVE", textFieldName, value.ToLower()); // expect upper case for oids <= 2 string mustBeUpper = string.Format("{0} = '{1}'", textFieldName, value.ToUpper()); var selection1 = new ConstraintNode("OBJECTID <= 2"); selection1.Nodes.Add(new ConstraintNode(mustBeUpper)); selection1.Nodes.Add(new ConstraintNode(ignoreCaseOverride)); IObject row1 = CreateRow(objectClass, 1, textFieldIndex, value.ToUpper()); IObject row2 = CreateRow(objectClass, 2, textFieldIndex, value.ToLower()); // incorrect case // expect lower case for oids > 2 string mustBeLower = string.Format("{0} = '{1}'", textFieldName, value.ToLower()); var selection2 = new ConstraintNode("OBJECTID > 2"); selection2.Nodes.Add(new ConstraintNode(mustBeLower)); selection2.Nodes.Add(new ConstraintNode(ignoreCaseOverride)); IObject row3 = CreateRow(objectClass, 3, textFieldIndex, value.ToLower()); IObject row4 = CreateRow(objectClass, 4, textFieldIndex, value.ToUpper()); // incorrect case IObject row5 = CreateRow(objectClass, 5, textFieldIndex, value.ToUpper()); // incorrect case var constraintNodes = new List <ConstraintNode> { selection1, selection2 }; var caseSensitiveTest = new QaConstraint(objectClass, constraintNodes); caseSensitiveTest.SetSqlCaseSensitivity(0, true); var caseSensitiveRunner = new QaTestRunner(caseSensitiveTest); Assert.AreEqual(0, caseSensitiveRunner.Execute(row1)); Assert.AreEqual(1, caseSensitiveRunner.Execute(row2)); Assert.AreEqual( "testtable,2: OID = 2: Invalid value combination: OBJECTID = 2; TEXTFIELD = 'aaa' [Constraints.ConstraintNotFulfilled]", caseSensitiveRunner.Errors[0].ToString()); caseSensitiveRunner.ClearErrors(); Assert.AreEqual(0, caseSensitiveRunner.Execute(row3)); Assert.AreEqual(1, caseSensitiveRunner.Execute(row4)); Assert.AreEqual( "testtable,4: OID = 4: Invalid value combination: OBJECTID = 4; TEXTFIELD = 'AAA' [Constraints.ConstraintNotFulfilled]", caseSensitiveRunner.Errors[0].ToString()); caseSensitiveRunner.ClearErrors(); Assert.AreEqual(1, caseSensitiveRunner.Execute(row5)); Assert.AreEqual( "testtable,5: OID = 5: Invalid value combination: OBJECTID = 5; TEXTFIELD = 'AAA' [Constraints.ConstraintNotFulfilled]", caseSensitiveRunner.Errors[0].ToString()); caseSensitiveRunner.ClearErrors(); var caseInsensitiveTest = new QaConstraint(objectClass, constraintNodes); selection2.Nodes.Add(new ConstraintNode(caseSensitiveOverride)); var caseInsensitiveRunner = new QaTestRunner(caseInsensitiveTest); Assert.AreEqual(0, caseInsensitiveRunner.Execute(row1)); Assert.AreEqual(0, caseInsensitiveRunner.Execute(row2)); Assert.AreEqual(0, caseInsensitiveRunner.Execute(row3)); Assert.AreEqual(1, caseInsensitiveRunner.Execute(row4)); Assert.AreEqual( "testtable,4: OID = 4: Invalid value combination: OBJECTID = 4; TEXTFIELD = 'AAA' [Constraints.ConstraintNotFulfilled]", caseInsensitiveRunner.Errors[0].ToString()); caseInsensitiveRunner.ClearErrors(); Assert.AreEqual(1, caseInsensitiveRunner.Execute(row5)); Assert.AreEqual( "testtable,5: OID = 5: Invalid value combination: OBJECTID = 5; TEXTFIELD = 'AAA' [Constraints.ConstraintNotFulfilled]", caseInsensitiveRunner.Errors[0].ToString()); caseInsensitiveRunner.ClearErrors(); }