< Summary

Information
Class: ValidateLib.TabularData.Validation.TabularDataTableValidator
Assembly: validatelib.dll
File(s): C:\skola_karlovka\RP\code\csv-validator\CSV_Validator\ValidateLib\TabularData\Validation\TabularDataTableValidator.cs
Line coverage
91%
Covered lines: 62
Uncovered lines: 6
Coverable lines: 68
Total lines: 170
Line coverage: 91.1%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

C:\skola_karlovka\RP\code\csv-validator\CSV_Validator\ValidateLib\TabularData\Validation\TabularDataTableValidator.cs

#LineLine coverage
 1using ValidateLib.Encoding.Bom;
 2using ValidateLib.ErrorsAndWarnings.Errors;
 3using ValidateLib.ErrorsAndWarnings.Warnings;
 4using ValidateLib.Metadata.Descriptors;
 5using ValidateLib.Results;
 6using ValidateLib.TabularData.AnnotatedTabularDataModel;
 7using ValidateLib.TabularData.Parsing;
 8using ValidateLib.TabularData.Validation.ValidationRules;
 9
 10namespace ValidateLib.TabularData.Validation
 11{
 12    /// <summary>
 13    /// validates tabular data files based on the metadata extracted either from
 14    /// metadata file or from embedded metadata.
 15    /// Uses classes that parses csv file.
 16    /// </summary>
 17    public class TabularDataTableValidator
 18    {
 19        const int BUFFER_SIZE = 10000;
 20        const int MINIMAL_CHARS_COUNT = 50;
 21        TableDescriptor _tableDescriptor;
 22        private int _numberOfForeingKeys = 0;
 123        protected List<ICellValidationRule> cellValidationRules { get; set; } = new List<ICellValidationRule>();
 124        protected List<IRowValidationRule> rowValidationRules { get; set; } = new List<IRowValidationRule>();
 125        public TabularDataTableValidator(TableDescriptor tableDescriptor, List<ICellValidationRule>? cellRules = null, L
 26        {
 27            // defualt rules set by use
 128            cellValidationRules.AddRange(GetDefaultCellValidationRules());
 129            rowValidationRules.AddRange(GetDefaultRowValidationRules());
 30
 31            // rules that the user can provide, maybe not the cleanest solution? TODO think about this
 132            if (cellRules != null)
 033                cellValidationRules.AddRange(cellRules);
 134            if (rowRules != null)
 135                rowValidationRules.AddRange(rowRules);
 136            this._tableDescriptor = tableDescriptor;
 37
 138            if (tableDescriptor.tableSchema is not null &&
 139                tableDescriptor.tableSchema._value is not null &&
 140                    tableDescriptor.tableSchema._value.foreignKeys is not null)
 41            {
 142                _numberOfForeingKeys = tableDescriptor.tableSchema._value.foreignKeys._value!.Count;
 43            }
 44
 45
 146        }
 47        private List<ICellValidationRule> GetDefaultCellValidationRules()
 48        {
 149            List<ICellValidationRule> rules = new List<ICellValidationRule>();
 150            rules.Add(new CellDatatypeValidationRule());
 151            rules.Add(new CellLengthValidationRule());
 152            rules.Add(new CellValueConstraintValidationRule());
 53
 154            return rules;
 55        }
 56
 57        private List<IRowValidationRule> GetDefaultRowValidationRules()
 58        {
 159            List<IRowValidationRule> rules = new List<IRowValidationRule>();
 160            rules.Add(new PrimaryKeyRowValidationRule());
 161            rules.Add(new NumberOfColumnsRowValidationRule());
 62
 163            return rules;
 64
 65        }
 166        private int GetMinimalCharsCount(Reader reader, Flags flags) => Math.Max(MINIMAL_CHARS_COUNT, Math.Max(reader.Ma
 67
 68        /// <summary>
 69        /// We need separate method for the TableGroup because we need to annotate the columns which are
 70        /// referenced from other schemes so we would remember the values during the parsing. I. e. set the
 71        /// correct flags for the Column objects inside the table.
 72        /// </summary>
 73        /// <param name="errors"></param>
 74        /// <param name="table"> annotated table with referenced columns flags set correctly</param>
 75        public void ValidateTable(ITableValidationDetail validationDetail, Table table)
 76        {
 77            try
 78            {
 179                ValidateTableUnsafe(validationDetail, table);
 180            }
 081            catch (Error e)
 82            {
 083                validationDetail.Errors.Add(e);
 084            }
 185            catch (Exception)
 86            {
 187                validationDetail.Errors.Add(ErrorFactory.GetUnknownError());
 188            }
 89
 90
 191        }
 92        void ValidateTableUnsafe(ITableValidationDetail validationDetail, Table table)
 93        {
 194            RowReader rowReader = new RowReader(_tableDescriptor._flags!);
 195            TabularDataCreator tabularDataCreator = new TabularDataCreator(_tableDescriptor._flags!, table);
 196            TabularDataAnnotator tabularDataAnottator = new TabularDataAnnotator(_tableDescriptor._flags!);
 97
 198            int minimalCharsCount = GetMinimalCharsCount(rowReader, _tableDescriptor._flags!);
 199            using (var fs = _tableDescriptor._fileWrapper!.OpenNewFileStream())
 100            {
 1101                ValidateTableWithWrapper(fs, minimalCharsCount, table, tabularDataAnottator, tabularDataCreator, rowRead
 1102            }
 1103        }
 104
 105        void ValidateTableWithWrapper(
 106            FileStream fs,
 107            int minimalCharsCount,
 108            Table table,
 109            TabularDataAnnotator tabularDataAnottator,
 110            TabularDataCreator tabularDataCreator,
 111            RowReader rowReader,
 112            ITableValidationDetail validationDetail,
 113            bool tableGroup = false
 114            )
 115        {
 116
 1117            if (BomDetector.ContainsUtf8Bom(fs))
 118            {
 0119                validationDetail.Warnings.Add(WarningFactory.GetBomPresentWarning(validationDetail.TableIRI));
 120            }
 121
 1122            CustomStreamReader csr = new CustomStreamReader(fs, BUFFER_SIZE, minimalCharsCount);
 123
 1124            tabularDataCreator.HandleHeaderAndSkipRows(csr);
 1125            tabularDataAnottator.AnnotateTable(table, _tableDescriptor);
 1126            if (!tableGroup)
 0127                tabularDataAnottator.CreateAnnotatedColumns(table, _tableDescriptor);
 128
 1129            Row? row = tabularDataCreator.CreateRow(csr, rowReader);
 130
 1131            while (row is not null)
 132            {
 1133                tabularDataAnottator.AnnotateRow(row, _tableDescriptor);
 1134                validationDetail.Errors.AddRange(row.errors);
 1135                validationDetail.Errors.AddRange(ValidateRow(row));
 1136                row = tabularDataCreator.CreateRow(csr, rowReader);
 137            }
 138
 1139            validationDetail.RowsProcessed = tabularDataCreator.rowsProcessed;
 1140            validationDetail.CellsProcessed = tabularDataCreator.cellsProcessed;
 1141            validationDetail.ColumnsProcessed = table.columns.Count;
 142
 1143        }
 144        public List<Error> ValidateRow(Row annotatedRow)
 145        {
 1146            List<Error> errors = new List<Error>();
 147
 1148            foreach (var rowRule in rowValidationRules)
 149            {
 1150                errors.AddRange(rowRule.ValidateRow(annotatedRow));
 151            }
 152
 1153            foreach (var cell in annotatedRow.cells)
 154            {
 1155                errors.AddRange(ValidateCell(cell));
 156            }
 1157            return errors;
 158
 159        }
 160
 161        private List<Error> ValidateCell(Cell annotatedCell)
 162        {
 1163            foreach (var rule in cellValidationRules)
 164            {
 1165                rule.ValidateCell(annotatedCell);
 166            }
 1167            return annotatedCell.errors;
 168        }
 169    }
 170}