| | 1 | | using ValidateLib.ErrorsAndWarnings.Errors; |
| | 2 | | using ValidateLib.ErrorsAndWarnings.Warnings; |
| | 3 | | using ValidateLib.Metadata.Descriptors; |
| | 4 | |
|
| | 5 | | namespace ValidateLib.Metadata.Validators |
| | 6 | | { |
| | 7 | | public class ForeignKeyValidator : IMValidator<TableGroupDescriptor> |
| | 8 | | { |
| 1 | 9 | | TableDescriptor? referencingTable { get; set; } |
| 1 | 10 | | ForeignKeyDescriptor? referencingFKDescriptor { get; set; } |
| | 11 | | public List<Warning> Validate(TableGroupDescriptor tableGroupDescriptor) |
| | 12 | | { |
| 1 | 13 | | foreach (var table in tableGroupDescriptor!.tables!._value!) |
| | 14 | | { |
| 1 | 15 | | ResolveForeignKeysForTable(table, tableGroupDescriptor); |
| | 16 | | } |
| 1 | 17 | | return new List<Warning>(); |
| | 18 | | } |
| | 19 | |
|
| | 20 | | void ResolveForeignKeysForTable(TableDescriptor table, TableGroupDescriptor tableGroupDescriptor) |
| | 21 | | { |
| 1 | 22 | | if (table.tableSchema is not null && table!.tableSchema?._value?.foreignKeys is not null) |
| | 23 | | { |
| 1 | 24 | | var foreignKeys = table.tableSchema._value.foreignKeys._value; |
| 1 | 25 | | var tableSchema = table.tableSchema._value; |
| 1 | 26 | | referencingTable = table; |
| 1 | 27 | | foreach (var foreignKeyDescriptor in foreignKeys!) |
| | 28 | | { |
| 1 | 29 | | var referencedSchema = FindReferencedSchema(tableGroupDescriptor, foreignKeyDescriptor); |
| 1 | 30 | | for (int i = 0; i < foreignKeyDescriptor.columnReference!._value!.Count; i++) |
| | 31 | | { |
| 1 | 32 | | var referencingColumn = foreignKeyDescriptor.columnReference._value[i]; |
| 1 | 33 | | var referencedColumn = foreignKeyDescriptor!.reference!._value!.columnReference!._value![i]!; |
| 1 | 34 | | if (!ColumnExistsWithName(tableSchema, referencingColumn)) ErrorFactory.ThrowReferencingColumnDo |
| 1 | 35 | | if (!ColumnExistsWithName(referencedSchema, referencedColumn)) ErrorFactory.ThrowReferencedColum |
| | 36 | |
|
| | 37 | | } |
| | 38 | | } |
| | 39 | | } |
| 1 | 40 | | } |
| | 41 | | static bool ColumnExistsWithName(SchemaDescriptor schemaDescriptor, string name) |
| | 42 | | { |
| 1 | 43 | | foreach (var column in schemaDescriptor?.columns?._value!) |
| | 44 | | { |
| 1 | 45 | | if (column.name is not null) |
| | 46 | | { |
| 1 | 47 | | if (column.name._value == name) return true; |
| | 48 | | } |
| | 49 | | } |
| 1 | 50 | | return false; |
| 1 | 51 | | } |
| | 52 | |
|
| | 53 | | SchemaDescriptor FindReferencedSchema(TableGroupDescriptor tableGroupDescriptor, ForeignKeyDescriptor foreignKey |
| | 54 | | { |
| 1 | 55 | | referencingFKDescriptor = foreignKeyDescriptor; |
| 1 | 56 | | if (foreignKeyDescriptor!.reference!._value!.schemaReference is not null) |
| | 57 | | { |
| 1 | 58 | | return FindReferencedSchemaDescriptorWithSchemaId(tableGroupDescriptor, foreignKeyDescriptor!.reference! |
| | 59 | | } |
| | 60 | | else |
| | 61 | | { |
| 1 | 62 | | return FindReferencedSchemaDescriptorWithTableUrl(tableGroupDescriptor, foreignKeyDescriptor!.reference. |
| | 63 | | } |
| | 64 | | } |
| | 65 | |
|
| | 66 | | public static TableDescriptor FindReferencedTable(TableGroupDescriptor tableGroupDescriptor, ForeignKeyDescripto |
| | 67 | | { |
| 1 | 68 | | ForeignKeyValidator fkValidator = new ForeignKeyValidator(); |
| 1 | 69 | | if (foreignKeyDescriptor!.reference!._value!.schemaReference is not null) |
| | 70 | | { |
| 1 | 71 | | return fkValidator.FindReferencedTableDescriptorWithSchemaId(tableGroupDescriptor, foreignKeyDescriptor! |
| | 72 | | } |
| | 73 | | else |
| | 74 | | { |
| 1 | 75 | | return fkValidator.FindReferencedTableDescriptorWithTableUrl(tableGroupDescriptor, foreignKeyDescriptor! |
| | 76 | | } |
| | 77 | | } |
| | 78 | | SchemaDescriptor FindReferencedSchemaDescriptorWithTableUrl(TableGroupDescriptor tableGroupDescriptor, string ta |
| | 79 | | { |
| 1 | 80 | | SchemaDescriptor? desiredSchema = null; |
| 1 | 81 | | foreach (var table in tableGroupDescriptor?.tables?._value!) |
| | 82 | | { |
| 1 | 83 | | if (table!.url!._value == tableUrl) |
| | 84 | | { |
| 1 | 85 | | if (desiredSchema is null) |
| | 86 | | { |
| 1 | 87 | | desiredSchema = table!.tableSchema!._value; |
| | 88 | | } |
| | 89 | | else |
| 0 | 90 | | ErrorFactory.ThrowTwoSatisfyingReferencedTablesErrorError(referencingTable!, referencingFKDescri |
| | 91 | |
|
| | 92 | | } |
| | 93 | | } |
| 1 | 94 | | if (desiredSchema is null) ErrorFactory.ThrowNoSatisfyingReferencedTableError(referencingTable!, referencing |
| 1 | 95 | | return desiredSchema!; |
| | 96 | | } |
| | 97 | |
|
| | 98 | | TableDescriptor FindReferencedTableDescriptorWithTableUrl(TableGroupDescriptor tableGroupDescriptor, string tabl |
| | 99 | | { |
| 1 | 100 | | TableDescriptor? desiredTable = null; |
| 1 | 101 | | foreach (var table in tableGroupDescriptor?.tables?._value!) |
| | 102 | | { |
| 1 | 103 | | if (table!.url!._value == tableUrl) |
| | 104 | | { |
| 1 | 105 | | if (desiredTable is null) |
| | 106 | | { |
| 1 | 107 | | desiredTable = table; |
| | 108 | | } |
| | 109 | | else |
| 0 | 110 | | ErrorFactory.ThrowTwoSatisfyingReferencedTablesErrorError(referencingTable!, referencingFKDescri |
| | 111 | |
|
| | 112 | | } |
| | 113 | | } |
| 1 | 114 | | if (desiredTable is null) ErrorFactory.ThrowNoSatisfyingReferencedTableError(referencingTable!, referencingF |
| 1 | 115 | | return desiredTable!; |
| | 116 | | } |
| | 117 | |
|
| | 118 | | SchemaDescriptor FindReferencedSchemaDescriptorWithSchemaId(TableGroupDescriptor tableGroupDescriptor, string sc |
| | 119 | | { |
| 1 | 120 | | SchemaDescriptor? desiredSchema = null; |
| 1 | 121 | | foreach (var table in tableGroupDescriptor?.tables?._value!) |
| | 122 | | { |
| 1 | 123 | | if (table.tableSchema is not null && table!.tableSchema._value!.id is not null) |
| | 124 | | { |
| 1 | 125 | | if (table!.tableSchema._value.id._value == schemaId) |
| | 126 | | { |
| 1 | 127 | | if (desiredSchema is null) |
| | 128 | | { |
| 1 | 129 | | desiredSchema = table.tableSchema._value; |
| | 130 | | } |
| | 131 | | else |
| 0 | 132 | | ErrorFactory.ThrowTwoSatisfyingReferencedTablesErrorError(referencingTable!, referencingFKDe |
| | 133 | |
|
| | 134 | | } |
| | 135 | | } |
| | 136 | |
|
| | 137 | | } |
| 1 | 138 | | if (desiredSchema is null) ErrorFactory.ThrowNoSatisfyingReferencedTableError(referencingTable!, referencing |
| 1 | 139 | | return desiredSchema!; |
| | 140 | | } |
| | 141 | |
|
| | 142 | | TableDescriptor FindReferencedTableDescriptorWithSchemaId(TableGroupDescriptor tableGroupDescriptor, string sche |
| | 143 | | { |
| 1 | 144 | | TableDescriptor? tableDescriptor = null; |
| 1 | 145 | | foreach (var table in tableGroupDescriptor?.tables?._value!) |
| | 146 | | { |
| 1 | 147 | | if (table.tableSchema is not null && table!.tableSchema._value!.id is not null) |
| | 148 | | { |
| 1 | 149 | | if (table!.tableSchema._value.id._value == schemaId) |
| | 150 | | { |
| 1 | 151 | | if (tableDescriptor is null) |
| | 152 | | { |
| 1 | 153 | | tableDescriptor = table; |
| | 154 | | } |
| | 155 | | else |
| 0 | 156 | | ErrorFactory.ThrowTwoSatisfyingReferencedTablesErrorError(referencingTable!, referencingFKDe |
| | 157 | |
|
| | 158 | | } |
| | 159 | | } |
| | 160 | |
|
| | 161 | | } |
| 1 | 162 | | if (tableDescriptor is null) ErrorFactory.ThrowNoSatisfyingReferencedTableError(referencingTable!, referenci |
| 1 | 163 | | return tableDescriptor!; |
| | 164 | | } |
| | 165 | |
|
| | 166 | | } |
| | 167 | | } |