Пример #1
0
        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);
        }
Пример #2
0
 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));
 }
Пример #3
0
 private MultiTableView CreateConstraintHelper([NotNull] ITable lineTable,
                                               [NotNull] ITable polyTable)
 {
     return(TableViewFactory.Create(
                new[] { lineTable, polyTable, polyTable },
                new[] { "B", "L", "R" },
                _constraint,
                GetSqlCaseSensitivity(lineTable, polyTable)));
 }
Пример #4
0
        public QueryFilterHelper([NotNull] ITable table,
                                 [CanBeNull] string constraint,
                                 bool caseSensitive)
        {
            const bool useAsConstraint = true;

            _tableView = TableViewFactory.Create(table, constraint, useAsConstraint,
                                                 caseSensitive);

            SubFields = _tableView.SubFields;
        }
Пример #5
0
        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));
        }
Пример #6
0
        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");
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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)));
        }
Пример #11
0
            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);
            }
Пример #12
0
        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));
        }
Пример #13
0
        /// <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());
            }
        }
Пример #14
0
        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);
        }
Пример #15
0
        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)));
        }
Пример #16
0
        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);
            }
        }
Пример #17
0
        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);
        }