private static TableView GetTableView([NotNull] ITable table, [CanBeNull] string fieldName, bool caseSensitive) { Assert.ArgumentNotNull(table, nameof(table)); if (fieldName != null) { // parse/remove/use case sensitivty hint bool?caseSensitivityOverride; fieldName = ExpressionUtils.ParseCaseSensitivityHint(fieldName, out caseSensitivityOverride); if (caseSensitivityOverride != null) { caseSensitive = caseSensitivityOverride.Value; } } const bool useAsConstraint = false; TableView result = TableViewFactory.Create(table, fieldName, useAsConstraint, caseSensitive); result.AddColumn(QaConnections.StartsIn, typeof(bool)); DataColumn fieldColumn = result.AddColumn(_expressionFieldName, typeof(object)); fieldColumn.Expression = fieldName; return(result); }
private IDictionary <int, TableView> CreateHelpers([NotNull] ITable table) { return(_tables.Where(t => t == table) .Select((t, i) => new KeyValuePair <int, TableView>( i, TableViewFactory.Create(t, GetConstraint(i)))) .ToDictionary(p => p.Key, p => p.Value)); }
private MultiTableView CreateConstraintHelper([NotNull] ITable lineTable, [NotNull] ITable polyTable) { return(TableViewFactory.Create( new[] { lineTable, polyTable, polyTable }, new[] { "B", "L", "R" }, _constraint, GetSqlCaseSensitivity(lineTable, polyTable))); }
public QueryFilterHelper([NotNull] ITable table, [CanBeNull] string constraint, bool caseSensitive) { const bool useAsConstraint = true; _tableView = TableViewFactory.Create(table, constraint, useAsConstraint, caseSensitive); SubFields = _tableView.SubFields; }
public void CanMatchRows() { const string textField1 = "Text1"; const string textField2 = "Text2"; const string textFieldBoth = "Text"; IFeatureClass fc1 = CreateFeatureClass("CanMatchRows_fc1", esriGeometryType.esriGeometryPolygon, FieldUtils.CreateTextField(textField1, 1), FieldUtils.CreateTextField(textFieldBoth, 1)); IFeatureClass fc2 = CreateFeatureClass("CanMatchRows_fc2", esriGeometryType.esriGeometryPolygon, FieldUtils.CreateTextField(textFieldBoth, 1), FieldUtils.CreateTextField(textField2, 1)); const bool caseSensitive = true; MultiTableView view = TableViewFactory.Create(new[] { (ITable)fc1, (ITable)fc2 }, new[] { "G1", "G2" }, "G1.TEXT1 = G2.TEXT2 AND G1.Text = 'x' AND G2.Text = 'y'", caseSensitive); IFeature f1A = fc1.CreateFeature(); f1A.Value[fc1.FindField(textField1)] = "A"; f1A.Value[fc1.FindField(textFieldBoth)] = "x"; f1A.Store(); IFeature f2A = fc2.CreateFeature(); f2A.Value[fc2.FindField(textField2)] = "A"; f2A.Value[fc2.FindField(textFieldBoth)] = "y"; f2A.Store(); Assert.IsTrue(view.MatchesConstraint(f1A, f2A)); Assert.AreEqual("G1.TEXT1 = 'A'; G2.TEXT2 = 'A'; G1.TEXT = 'x'; G2.TEXT = 'y'", view.ToString(f1A, f2A)); IFeature f1B = fc1.CreateFeature(); f1B.Value[fc1.FindField(textField1)] = "b"; f1B.Value[fc1.FindField(textFieldBoth)] = "x"; f1B.Store(); IFeature f2B = fc2.CreateFeature(); f2B.Value[fc2.FindField(textField2)] = "B"; // different case --> no match f2B.Value[fc2.FindField(textFieldBoth)] = "y"; f2B.Store(); Assert.IsFalse(view.MatchesConstraint(f1B, f2B)); Assert.AreEqual("G1.TEXT1 = 'b'; G2.TEXT2 = 'B'; G1.TEXT = 'x'; G2.TEXT = 'y'", view.ToString(f1B, f2B)); }
private static void AssertFilteredMultiViewRowCount( int expectedCount, [NotNull] string expression, [NotNull] IFeatureClass featureClass, [NotNull] IFeature feature, [NotNull] ITable table, [NotNull] IRow row) { MultiTableView view = TableViewFactory.Create(new[] { (ITable)featureClass, table }, new[] { "F", "T" }, expression); view.Add(feature, row); Assert.AreEqual(expectedCount, view.FilteredRowCount, "Unexpected filtered row count"); }
private TableView CreateDangleCountExpression( [NotNull] IFeatureClass polylineClass, [NotNull] string dangleCountExpression) { TableView tableView = TableViewFactory.Create( (ITable)polylineClass, dangleCountExpression, false, GetSqlCaseSensitivity((ITable)polylineClass)); tableView.AddColumn(_dangleCountPlaceHolder, typeof(int)); tableView.Constraint = dangleCountExpression; return(tableView); }
private static TableView CreateTableView([NotNull] string expression, params IFeature[] features) { Assert.ArgumentCondition(features.Length > 0, "no feature"); var table = (ITable)features[0].Class; const bool useAsConstraint = true; TableView view = TableViewFactory.Create(table, expression, useAsConstraint); foreach (IFeature feature in features) { view.Add(feature); } return(view); }
private static void CreateNodeHelpers( [NotNull] ITable table, [NotNull] ICollection <ConstraintNode> constraints, bool caseSensitive) { string concatenatedConditions = ConcatenateConditions(constraints); if (!string.IsNullOrEmpty(concatenatedConditions)) { const bool useAsConstraint = true; TableView baseHelper = TableViewFactory.Create(table, concatenatedConditions, useAsConstraint, caseSensitive); baseHelper.Constraint = string.Empty; CreateHelpers(constraints, baseHelper); } }
protected override int ExecuteCore(IRow row, int tableIndex) { if (!_usesSimpleConstraint) { if (!_constraintNodesInitialized) { CreateNodeHelpers(_table, _constraintNodes, GetSqlCaseSensitivity(tableIndex)); _constraintNodesInitialized = true; } return(CheckNodes(row, _constraintNodes, new List <TableView>())); } if (_simpleConstraintHelper == null) { const bool useAsConstraint = true; _simpleConstraintHelper = TableViewFactory.Create(_table, _constraint, useAsConstraint, GetSqlCaseSensitivity( tableIndex)); } if (_simpleConstraintHelper.MatchesConstraint(row)) { return(NoError); } string description = _simpleConstraintHelper.ToString(row, constraintOnly: true); if (StringUtils.IsNullOrEmptyOrBlank(description)) { description = _simpleConstraintHelper.Constraint?.Trim(); if (string.IsNullOrEmpty(description)) { description = "<no constraint>"; } } return(ReportError(description, GetErrorGeometry(row), Codes[Code.ConstraintNotFulfilled], GetSimpleConstraintAffectedComponent(), GetInvolvedRows(row))); }
private static TableView CreateTableView([NotNull] ITable table, [NotNull] string fieldName, [NotNull] string condition, bool caseSensitive) { if (StringUtils.IsNullOrEmptyOrBlank(condition)) { return(null); } TableView result = TableViewFactory.Create(table, condition, caseSensitive: caseSensitive, useAsConstraint: false); result.AddColumn(_valueFieldName, GetFieldType(table, fieldName)); result.Constraint = condition; return(result); }
public void CanUseShapeAreaAlias() { IFeatureClass fc1 = CreateFeatureClass("CanUseShapeAreaAlias_fc1", esriGeometryType.esriGeometryPolygon); IFeatureClass fc2 = CreateFeatureClass("CanUseShapeAreaAlias_fc2", esriGeometryType.esriGeometryPolygon); const bool caseSensitive = true; MultiTableView view = TableViewFactory.Create(new[] { (ITable)fc1, (ITable)fc2 }, new[] { "G1", "G2" }, "G1.$ShapeArea < G2.$ShapeArea", caseSensitive); IFeature f1A = fc1.CreateFeature(); f1A.Shape = GeometryFactory.CreatePolygon(0, 0, 10, 10); f1A.Store(); IFeature f1B = fc1.CreateFeature(); f1B.Shape = GeometryFactory.CreatePolygon(0, 0, 100, 100); f1B.Store(); IFeature f2A = fc2.CreateFeature(); f2A.Shape = GeometryFactory.CreatePolygon(0, 0, 100, 100); f2A.Store(); IFeature f2B = fc2.CreateFeature(); f2B.Shape = GeometryFactory.CreatePolygon(0, 0, 10, 10); f2B.Store(); Assert.IsTrue(view.MatchesConstraint(f1A, f2A)); Assert.AreEqual("G1.$SHAPEAREA = 100; G2.$SHAPEAREA = 10000", view.ToString(f1A, f2A)); Assert.IsFalse(view.MatchesConstraint(f1B, f2B)); Assert.AreEqual("G1.$SHAPEAREA = 10000; G2.$SHAPEAREA = 100", view.ToString(f1B, f2B)); }
/// <summary> /// create a filter that gets the lines crossing the current row, /// with the same attribute constraints as the table /// </summary> private void InitFilter() { IList <ISpatialFilter> spatialFilters; IList <QueryFilterHelper> filterHelpers; // there is one table and hence one filter (see constructor) // Create copy of this filter and use it for quering crossing lines CopyFilters(out spatialFilters, out filterHelpers); _spatialFilter = spatialFilters[0]; _selectHelper = filterHelpers[0]; _spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches; if (_constraint != null) { _compareHelper = TableViewFactory.Create( new[] { InvolvedTables[0], InvolvedTables[0] }, new[] { "L", "R" }, _constraint, GetSqlCaseSensitivity()); } }
public static IList <QaConnectionRuleHelper> CreateList( [NotNull] IList <QaConnectionRule> rules, [NotNull] out TableView[] tableFilterHelpers) { IList <ITable> tableList = rules[0].TableList; foreach (QaConnectionRule rule in rules) { if (tableList != rule.TableList) { throw new InvalidOperationException( "All TableLists of the rules must be the same."); } } var result = new List <QaConnectionRuleHelper>(rules.Count); int tableCount = tableList.Count; tableFilterHelpers = new TableView[tableCount]; var baseConditions = new StringBuilder[tableCount]; foreach (QaConnectionRule rule in rules) { for (int i = 0; i < tableCount; i++) { string selectionExpression = rule.SelectionExpressions[i]; if (!StringUtils.IsNotEmpty(selectionExpression)) { continue; } if (baseConditions[i] == null) { baseConditions[i] = new StringBuilder(selectionExpression); } else { baseConditions[i].AppendFormat(" AND {0}", selectionExpression); } } if (rule.Constraint != null) { foreach ( KeyValuePair <string, QaConnectionCountRule> pair in rule.CountRulesByVariableName) { int i = tableList.IndexOf(pair.Value.Table); baseConditions[i] .AppendFormat(" AND {0}", pair.Value.CountSelectionExpression); } } } string startsInLower = QaConnections.StartsIn.ToLower(); for (int tableIndex = 0; tableIndex < tableCount; tableIndex++) { ITable table = tableList[tableIndex]; string lowerCaseCondition = baseConditions[tableIndex].ToString().ToLower().Replace(startsInLower, "true"); TableView tableFilterHelper = TableViewFactory.Create(table, lowerCaseCondition); tableFilterHelper.Constraint = null; if (((IFeatureClass)table).ShapeType == esriGeometryType.esriGeometryPolyline) { tableFilterHelper.AddColumn(QaConnections.StartsIn, typeof(bool)); } tableFilterHelpers[tableIndex] = tableFilterHelper; } foreach (QaConnectionRule rule in rules) { var newRuleHelper = new QaConnectionRuleHelper(tableList); for (int i = 0; i < tableCount; i++) { string selectionExpression = rule.SelectionExpressions[i]; if (!StringUtils.IsNotEmpty(selectionExpression)) { continue; } TableView filterHelper = tableFilterHelpers[i].Clone(); filterHelper.Constraint = selectionExpression; newRuleHelper.MainRuleFilterHelpers[i] = filterHelper; } if (rule.Constraint != null) { string constraint = rule.Constraint; int i = 0; foreach ( KeyValuePair <string, QaConnectionCountRule> pair in rule.CountRulesByVariableName) { constraint = constraint.Replace(pair.Key, "{" + i + "}"); int tableIndex = tableList.IndexOf(pair.Value.Table); TableView helper = tableFilterHelpers[tableIndex].Clone(); helper.Constraint = pair.Value.CountSelectionExpression; newRuleHelper.AddCountRuleFilterHelper(helper); i++; } newRuleHelper.CountFilter = constraint; } result.Add(newRuleHelper); } return(result); }
private int CheckRows([NotNull] IList <NetElement> connectedElements) { if (_tableViews == null) { _tableViews = CreateTableViews(); } foreach (TableView tableView in _tableViews) { tableView.ClearRows(); } IList <NetElement> elementsToCheck; if (_allowedPointsExpressions != null) { if (_allowedPointsTableViews == null) { const bool useAsConstraint = true; var allowedPointsTableViews = new List <TableView>(_pointClasses.Count); for (var pointClassIndex = 0; pointClassIndex < _pointClasses.Count; pointClassIndex++) { string allowPointsExpression = _allowedPointsExpressions.Count == 1 ? _allowedPointsExpressions[0] : _allowedPointsExpressions[ pointClassIndex]; TableView allowedPointsTableView = TableViewFactory.Create( (ITable)_pointClasses[pointClassIndex], allowPointsExpression, useAsConstraint, GetSqlCaseSensitivity(pointClassIndex + _pointClassesMinIndex)); allowedPointsTableViews.Add(allowedPointsTableView); } _allowedPointsTableViews = allowedPointsTableViews; } // if there are points at the connection, and they are all allowed junctions, // then no further checks are needed if (HasPointsAndAllAreAllowed(connectedElements, out elementsToCheck, _allowedPointsTableViews)) { return(NoError); } } else { elementsToCheck = connectedElements; } // if constraint is based on most frequent line value, or if line values must be unique: *all* field values are needed bool getAllLineFieldValues = _pointFieldValuesConstraint == PointFieldValuesConstraint.AllEqualAndMatchMostFrequentLineValue || _lineFieldValuesConstraint == LineFieldValuesConstraint.UniqueOrValidPointExists; List <object> distinctPointFieldValues; List <object> lineFieldValues; int pointCount; List <IRow> connectedRows = GetConnectedRows(elementsToCheck, getAllLineFieldValues, out lineFieldValues, out distinctPointFieldValues, out pointCount); string pointMessage; bool pointConstraintValid = IsPointConstraintFulfilled( distinctPointFieldValues, lineFieldValues, out pointMessage); bool validPointExists = pointCount > 0 && pointConstraintValid; bool isLineFieldValuesListDistinct = !getAllLineFieldValues; string lineMessage; bool lineConstraintValid = IsLineConstraintFulfilled( lineFieldValues, isLineFieldValuesListDistinct, validPointExists, out lineMessage); if (pointConstraintValid && lineConstraintValid) { return(NoError); } IssueCode issueCode = GetIssueCode(pointConstraintValid, lineConstraintValid); string description = GetErrorDescription(pointConstraintValid, lineConstraintValid, pointMessage, lineMessage); return(ReportError(description, elementsToCheck[0].NetPoint, issueCode, null, GetInvolvedRows(connectedRows))); }
public void TestExpression() { const string intField = "Int"; const string doubleField = "Dbl"; IFieldsEdit fields = new FieldsClass(); fields.AddField(FieldUtils.CreateOIDField()); fields.AddField(FieldUtils.CreateIntegerField(intField)); fields.AddField(FieldUtils.CreateDoubleField(doubleField, doubleField)); ITable tbl = DatasetUtils.CreateTable(_testWs, "TestExpression", null, fields); const int n = 10; for (var i = 0; i < n; i++) { IRow row = tbl.CreateRow(); row.set_Value(1, i); row.set_Value(2, i); row.Store(); } const double x = 2; string expression = string.Format("{0}, {1}, {2}", x, intField, doubleField); const bool useAsConstraint = false; TableView view = TableViewFactory.Create(tbl, expression, useAsConstraint); DataColumn constColumn = view.AddColumn("constValue", typeof(double)); constColumn.Expression = x.ToString(CultureInfo.InvariantCulture); DataColumn intColumn = view.AddColumn("intValue", typeof(double)); intColumn.Expression = intField; DataColumn exprColumn = view.AddColumn("exprValue", typeof(double)); exprColumn.Expression = string.Format("2.3 * {0} + 1.2 * {1}", doubleField, intField); DataColumn doubleColumn = view.AddColumn("doubleValue", typeof(double)); doubleColumn.Expression = doubleField; foreach (IRow row in new EnumCursor(tbl, null, false)) { view.ClearRows(); var i = (int)row.Value[1]; var d = (double)row.Value[2]; DataRow expressionRow = Assert.NotNull(view.Add(row)); var constVal = (double)expressionRow[constColumn.ColumnName]; NUnit.Framework.Assert.AreEqual(x, constVal); var intVal = (double)expressionRow[intColumn.ColumnName]; NUnit.Framework.Assert.AreEqual(i, intVal); var doubleVal = (double)expressionRow[doubleColumn.ColumnName]; NUnit.Framework.Assert.AreEqual(d, doubleVal); var exprVal = (double)expressionRow[exprColumn.ColumnName]; NUnit.Framework.Assert.AreEqual(2.3 * d + 1.2 * i, exprVal); } }
private TableView CreateHelper(int tableIndex) { ITable table = _tables[tableIndex]; // all used expressions must exist in all tables // TODO parse/remove/use case sensitivity hint string expressions = _groupByExpressions[tableIndex] + "," + _distinctExpressions[tableIndex]; var filterExpression = GetValueForTable(tableIndex, _existsRowGroupFiltersSql); if (filterExpression != null) { expressions = expressions + "," + filterExpression; } bool caseSensitivity = GetSqlCaseSensitivity(tableIndex); if (_relatedTables != null) { foreach (var rt in _relatedTables.Related .Where(t => t.OidFieldIndex >= 0)) { expressions = AddField(expressions, rt.FullOidFieldName); } } TableView helper = TableViewFactory.Create( table, expressions, useAsConstraint: false, caseSensitive: caseSensitivity); helper.Constraint = string.Empty; DataColumn groupByColumn = helper.AddColumn(_groupByColumn, typeof(object)); // TODO parse/remove/use case sensitivty hint groupByColumn.Expression = _groupByExpressions[tableIndex]; DataColumn distinctColumn = helper.AddColumn(_distinctColumn, typeof(object)); // TODO parse/remove/use case sensitivty hint distinctColumn.Expression = _distinctExpressions[tableIndex]; if (_relatedTables != null) { _relatedOidFields = new Dictionary <RelatedTable, int>(); foreach (RelatedTable relatedTable in _relatedTables.Related) { if (relatedTable.OidFieldIndex < 0) { _relatedOidFields.Add(relatedTable, -1); continue; } int oidIndex = helper.GetColumnIndex(relatedTable.FullOidFieldName); _relatedOidFields.Add(relatedTable, oidIndex); } } helper.ClearRows(); return(helper); }