internal static PkItem MakeIntersectTypeId(Dictionary<string, List<string>> fkPkCols, List<string> iFks, string tableName) { var keyProperties = new Dictionary<string, List<ColumnMetadata>>(); //get all key-property foreach (var pkFkColumnName in iFks) { var iFkMatchingJson = (DbContainers.AllColumns.Data.FirstOrDefault( x => string.Equals(x.table_name, tableName, C) && string.Equals(x.column_name, pkFkColumnName, C))); if (iFkMatchingJson == null) continue; if (!keyProperties.ContainsKey(pkFkColumnName)) keyProperties.Add(pkFkColumnName, new List<ColumnMetadata>()); keyProperties[pkFkColumnName].Add(iFkMatchingJson); } var keyManyToOnes = new Dictionary<string, List<ColumnMetadata>>(); //get all key-many-to-one foreach (var pkFkConstraintName in fkPkCols.Keys) { var sc = DbContainers.Fks.Data.FirstOrDefault( x => string.Equals(x.table_name, tableName) && string.Equals(x.constraint_name, pkFkConstraintName)); if (sc == null) continue; var matchedTableEntry = DbContainers.Pks.Data.FirstOrDefault(x => string.Equals(x.constraint_name, sc.unique_constraint_name)); //try again on the all-keys json if (matchedTableEntry == null) matchedTableEntry = DbContainers.AllKeys.Data.FirstOrDefault(x => string.Equals(x.constraint_name, sc.unique_constraint_name)); //still missing then get it from index-names if (matchedTableEntry == null) matchedTableEntry = DbContainers.AllIndex.Data.FirstOrDefault(x => string.Equals(x.constraint_name, sc.unique_constraint_name)); if (matchedTableEntry == null) continue; //database axiom 4.) a foreign-key, in addition to its table, may reference only one seperate table. var matchedTable = matchedTableEntry.table_name; //intend to use the table_name to which the FK references with value as manifold of columns on this table var fkPkColsJson = new List<ColumnMetadata>(); foreach (var rematchedColName in fkPkCols[pkFkConstraintName]) { foreach (var columnJsonData in DbContainers.Fks.Data.Where( x => string.Equals(x.table_name, tableName, C) && string.Equals(x.column_name, rematchedColName, C) && string.Equals(x.constraint_name, pkFkConstraintName, C))) { columnJsonData.constraint_name = pkFkConstraintName; fkPkColsJson.Add(columnJsonData); } } if(!keyManyToOnes.ContainsKey(matchedTable)) keyManyToOnes.Add(matchedTable, new List<ColumnMetadata>()); keyManyToOnes[matchedTable].AddRange(fkPkColsJson); } var keys = new PkItem(); if (keyProperties.Keys.Count > 0) keys.KeyProperty = keyProperties; if (keyManyToOnes.Keys.Count > 0) keys.KeyManyToOne = keyManyToOnes; return keys; }
/// <summary> /// Generates JSON formatted file whose contents are of form and fit to id nodes of an hbm.xml file. /// This is the first of the three hbm sorting cmdlets that should /// be called. /// /// The effort of this cmdlet is to determine, of all /// tables having a primary key, if a table is of a simple identity /// type or of a composite type. Furthermore, of the composite types /// what portion of the tables Foreign-Keys form apart of this /// composite primary key. /// </summary> /// <returns></returns> public static SortedKeys GetHbmDbPkData() { Settings.LoadOutputPathCurrentSettings(); var pkJson = DbContainers.Pks.Data; var aidJson = DbContainers.AutoIncrement.Data; //get table names var allTables = pkJson.Select(x => x.table_name).Distinct(); var singlePkTables = new List<string>(); var compositePkTables = new List<string>(); var keys = new Dictionary<string, PkItem>(); //divide tables between composite and singular pks foreach (var tbl in allTables) { var pkColCount = pkJson.Count(x => string.Equals(x.table_name, tbl, C)); if (pkColCount > 1) compositePkTables.Add(tbl); else singlePkTables.Add(tbl); } //divide composite pks between primitive keys and class-type keys foreach (var tbl in compositePkTables) { //get pks as a manifold of resident columns var pkManifold = GetHbmDistinctPks(tbl); //get fks as manifold of resident columns var fkManifold = GetHbmDistinctFks(tbl); //find the FKs which are PKs var fkPkCols = GetHbmFksWhichArePks(pkManifold, fkManifold); //get whatever independent FKs which remain, not being part of the PK var iFks = GetHbmFkNotInPksRemainder(pkManifold, fkPkCols); var compKeys = MakeIntersectTypeId(fkPkCols, iFks, tbl); keys.Add(tbl, compKeys); } foreach (var tbl in singlePkTables) { var simpleKeys = new PkItem(); var pkJsonTblValue = pkJson.First(x => string.Equals(x.table_name, tbl, C)); var isAutoIncrement = aidJson.Any(x => string.Equals(x.table_name, pkJsonTblValue.table_name, C)); pkJsonTblValue.is_auto_increment = isAutoIncrement; simpleKeys.Id = pkJsonTblValue; keys.Add(tbl, simpleKeys); } //this performs the write to disk return new SortedKeys { Data = keys }; }