< Summary

Information
Class: ValidateLib.TabularData.Validation.TabularDataAnnotator
Assembly: validatelib.dll
File(s): C:\skola_karlovka\RP\code\csv-validator\CSV_Validator\ValidateLib\TabularData\Validation\TabularDataAnnotator.cs
Line coverage
96%
Covered lines: 97
Uncovered lines: 4
Coverable lines: 101
Total lines: 190
Line coverage: 96%
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\TabularDataAnnotator.cs

#LineLine coverage
 1using ValidateLib.Metadata.Descriptors;
 2using ValidateLib.Metadata.Properties;
 3using ValidateLib.TabularData.AnnotatedTabularDataModel;
 4using ValidateLib.TabularData.Parsing;
 5
 6namespace ValidateLib.TabularData.Validation
 7{
 8    /// <summary>
 9    /// Creates annotated tabular data model needed for parsing and validation
 10    /// of tabular data files.
 11    /// </summary>
 12    public class TabularDataAnnotator
 13    {
 114        protected Flags flags { get; set; }
 15
 116        public TabularDataAnnotator(Flags flags)
 17        {
 118            this.flags = flags;
 119        }
 20
 21        public void AnnotateTable(Table table, TableDescriptor tableDescriptor)
 22        {
 123            tableDescriptor.table = table;
 124            table.tableDirection = tableDescriptor.tableDirection._value!;
 125            table.notes = tableDescriptor.notes is null ? new List<NoteDescriptor>() : tableDescriptor.notes._value!;
 126            table.suppressOutput = tableDescriptor.suppressOutput is null ? false : tableDescriptor.suppressOutput._valu
 127            table.transformations = tableDescriptor.transformations is null ? null : tableDescriptor.transformations._va
 128            table.url = tableDescriptor.url is null ? null : tableDescriptor.url._value;
 29
 130            if (tableDescriptor.tableSchema is null || tableDescriptor.tableSchema._value is null)
 131                return;
 132            SchemaDescriptor tableSchema = tableDescriptor.tableSchema._value;
 133            table.foreignKeys = tableSchema.foreignKeys is null ? new List<ForeignKeyDescriptor>() : tableSchema.foreign
 134            table.id = tableSchema.id is null ? null : tableSchema.id._value;
 135            table.schema = tableSchema;
 136        }
 37
 38        /// <summary>
 39        /// Creates annotated columns before actually parsing the tabular file only from metadata file.
 40        /// We need to do this beforehand because we need to know which cells to save to columns for later
 41        /// primary and foreign keys checks.
 42        /// </summary>
 43        /// <param name="table"></param>
 44        /// <param name="tableDescriptor"></param>
 45        /// <exception cref="ArgumentException"> Occurs when this is called twice on the same table </exception>
 46        public void CreateAnnotatedColumns(Table table, TableDescriptor tableDescriptor)
 47        {
 148            if (tableDescriptor.tableSchema is null ||
 149                tableDescriptor.tableSchema._value is null ||
 150                    tableDescriptor.tableSchema._value.columns is null ||
 151                        tableDescriptor.tableSchema._value.columns._value is null) return;
 52
 153            var columns = tableDescriptor.tableSchema._value.columns._value;
 54
 155            if (table.columns.Count != 0)
 056                throw new ArgumentException("CreateAnnotatedColumns called twice");
 57
 158            int sourceColumnNumber = 1 + flags.skipColumns;
 159            List<Column> annotatedColumns = new List<Column>();
 160            for (int i = flags.skipColumns; i < columns.Count; i++)
 61            {
 162                int iFromAlgorithm = i - flags.skipColumns + 1;
 163                ColumnDescriptor columnDescriptor = columns[i];
 64
 65
 166                Column column = new Column(table, iFromAlgorithm, sourceColumnNumber)
 167                {
 168                    name = columnDescriptor.name is null ? null : columnDescriptor!.name!._value!,
 169                    titles = columnDescriptor.titles is null ? new Dictionary<string, string[]>() : columnDescriptor.tit
 170                    _virtual = columnDescriptor._virtual is null ? false : columnDescriptor._virtual._value,
 171                    suppresOutput = columnDescriptor.suppresOutput is null ? false : columnDescriptor.suppresOutput._val
 172                    datatype = columnDescriptor.datatype is null ? new DatatypeDescriptor() : columnDescriptor.datatype.
 173                    _default = columnDescriptor._default is null ? "" : columnDescriptor._default._value,
 174                    lang = columnDescriptor.lang is null ? "und" : columnDescriptor.lang._value,
 175                    _null = columnDescriptor._null is null ? new List<string> { "" } : columnDescriptor._null._value!,
 176                    ordered = columnDescriptor.ordered is null ? false : columnDescriptor.ordered._value,
 177                    required = columnDescriptor.required is null ? false : columnDescriptor.required._value,
 178                    separator = columnDescriptor.separator is null ? null : columnDescriptor.separator._value,
 179                    textDirection = columnDescriptor.textDirection is null ? "auto" : columnDescriptor.textDirection._va
 180                    aboutURL = columnDescriptor.aboutURL is null ? null : columnDescriptor.aboutURL,
 181                    propertyURL = columnDescriptor.propertyUrl is null ? null : columnDescriptor.propertyUrl,
 182                    valueURL = columnDescriptor.valueUrl is null ? null : columnDescriptor.valueUrl,
 183                };
 84
 185                annotatedColumns.Add(column);
 186                sourceColumnNumber++;
 87            }
 88
 189            var tableSchemaDescriptor = tableDescriptor.tableSchema._value;
 190            if (tableSchemaDescriptor.primaryKey is not null)
 191                SetPrimaryKeysForColumns(tableSchemaDescriptor.primaryKey, annotatedColumns);
 92
 193            if (tableSchemaDescriptor.foreignKeys is not null && tableSchemaDescriptor.foreignKeys._value is not null)
 194                SetForeignKeysForColumns(tableSchemaDescriptor.foreignKeys._value, annotatedColumns);
 95
 196            table.columns = annotatedColumns;
 197        }
 98        /// <summary>
 99        /// Annotates one row in tabular data model.
 100        /// </summary>
 101        /// <param name="row"></param>
 102        /// <param name="tableDescriptor"></param>
 103        public void AnnotateRow(Row row, TableDescriptor tableDescriptor)
 104        {
 1105            if (tableDescriptor.tableSchema is null ||
 1106                tableDescriptor.tableSchema._value is null ||
 1107                    tableDescriptor.tableSchema._value.columns is null ||
 1108                        tableDescriptor.tableSchema._value.columns._value is null) return;
 109
 110            // the row can have less columns which would lead to an error during the validation
 1111            int columnsCount = Math.Min(row.table.columns.Count, row.cells.Count);
 112
 1113            row.table = tableDescriptor.table!;
 1114            row.primaryKeyDescriptor = tableDescriptor?.tableSchema?._value?.primaryKey;
 115            // we expect that the columns are created based on the table descriptor so the number
 116            // of columns should be the same
 1117            if (tableDescriptor.tableSchema._value.columns._value.Count != row.table.columns.Count)
 0118                throw new ArgumentException("Wrong usage of annotate row");
 119
 1120            for (int i = 0; i < columnsCount; i++)
 121            {
 1122                Cell cell = row.cells[i];
 1123                AnnotateCell(cell, tableDescriptor.tableSchema._value.columns._value[i]);
 124            }
 1125        }
 126
 127        protected void AnnotateCell(Cell cell, ColumnDescriptor columnDescriptor)
 128        {
 129            // add cell for later primary and foreign key checks
 1130            if (cell.column!.isPartOfKey())
 1131                cell.column!.cells.Add(cell);
 132
 1133            cell.aboutURL = columnDescriptor.aboutURL is null ? null : columnDescriptor.aboutURL;
 1134            cell.ordered = columnDescriptor.ordered is null ? false : columnDescriptor.ordered._value;
 1135            cell.propertyURL = columnDescriptor.aboutURL is null ? null : columnDescriptor.aboutURL;
 1136            cell.textDirection = columnDescriptor.textDirection is null ? "auto" : columnDescriptor.textDirection._value
 1137            cell.valueURL = columnDescriptor.valueUrl is null ? null : columnDescriptor.valueUrl;
 1138        }
 139
 140
 141        protected void SetPrimaryKeysForColumns(ColumnReferenceProperty primaryKey, List<Column> columns)
 142        {
 1143            if (primaryKey._value is null)
 0144                return;
 1145            List<string> primaryKeyVal = primaryKey._value;
 146
 1147            if (primaryKeyVal.Count == 0)
 0148                return;
 149
 1150            foreach (Column column in columns)
 151            {
 1152                if (column.name is not null && primaryKeyVal.Contains(column.name))
 153                {
 1154                    column.isPartOfPrimaryKey = true;
 155                }
 156            }
 1157        }
 158
 159        protected void SetForeignKeysForColumns(List<ForeignKeyDescriptor> foreignKeys, List<Column> columns)
 160        {
 1161            if (foreignKeys.Count == 0) return;
 162
 1163            foreach (var column in columns)
 164            {
 1165                if (IsPartOfForeingKey(column.name, foreignKeys))
 1166                    column.isPartOfForeignKey = true;
 167
 168            }
 1169        }
 170
 171        protected bool IsPartOfForeingKey(string? columnName, List<ForeignKeyDescriptor> foreignKeys)
 172        {
 1173            if (columnName is null) return false;
 174
 1175            foreach (ForeignKeyDescriptor foreignKeyDescriptor in foreignKeys)
 176            {
 1177                if (
 1178                    foreignKeyDescriptor.columnReference is not null
 1179                    && foreignKeyDescriptor.columnReference._value is not null
 1180                    )
 181                {
 1182                    if (foreignKeyDescriptor.columnReference._value.Contains(columnName))
 1183                        return true;
 184                }
 185            }
 186
 1187            return false;
 1188        }
 189    }
 190}