'use strict'; import * as schema from "./templates/schema" // @ts-ignore import MSSQLDatabaseDiscovery from './MSSQLDatabaseDiscovery'; // @ts-ignore import Converter from './src/utils/Converter'; const jsonMerger = require("json-merger"); //https://github.com/boschni/json-merger const Graph = require("./utils/graph-data-structure"); const _ = require('lodash'); export default class MSSQLSchemaGraph { buildEdges = async (foreignKeyReferences) => { let serializedLink let serializedLinks let edgesJson = { edges: {} } let edgeName: string; //foreign key column name let sourceNode: string; //foreign key table name let targetNode: string; //primary key table name //console.log(JSON.stringify(foreignKeyReferences, null, 3)) let graph = new Graph(); let tables = Object.keys(foreignKeyReferences) for (let i = 0; i < tables.length; i++) { let references = foreignKeyReferences[tables[i]] if (references.length === 0) { continue } sourceNode = tables[i] for (let j = 0; j < references.length; j++) { let reference = references[j] targetNode = reference['refTable'] edgeName = reference['ColName'] //console.log(sourceNode) graph.addNode(sourceNode) //original table graph.addNode(targetNode) //foreign table graph.addEdge(sourceNode, targetNode) } serializedLinks = graph.serializeLinks(edgeName) edgesJson.edges[sourceNode] = serializedLinks[edgeName]; graph = new Graph() serializedLinks = {} } //console.log(JSON.stringify(edgesJson,null,3)) //update the edges name edgesJson = await this.updateEdgeNames(edgesJson, foreignKeyReferences); //console.log(JSON.stringify(edgesJson,null,3)); return edgesJson } //update the edgeName to be the right one because if multiple elements in a table, then all the edgeName are the same //the edgename in an array should be diffent updateEdgeNames = (edges, foreignKeyReferences) => { //get the table name let tables = Object.keys(foreignKeyReferences) for (let i = 0; i < tables.length; i++) { let table = tables[i] let references = foreignKeyReferences[table] if (references.length === 0) { continue } for (let j = 0; j < references.length; j++) { let reference = references[j] let edgeName = reference['ColName'] edges['edges'][table][j]['edgeName'] = edgeName } } return edges } //to achieve the bidirectional relationship so we need to create edges that comes from target to source generateBidirectionalEdges = (edges) => { //get the table name let tables = Object.keys(edges['edges']) //console.log(tables) let _tables = {} let _references = [] for (let i = 0; i < tables.length; i++) { let table = tables[i] let references = edges['edges'][table] //console.log(references) let source let target for (let j = 0; j < references.length; j++) { let reference = references[j] let _reference = { ...reference } //generate the reverse edges source = reference['source'] let tmp = source target = reference['target'] _reference.source = target _reference.target = tmp _references.push(_reference) } } //create a json with arrays group by the tablename const property = "source" const reversedEdges = _.groupBy(_references, property); //combine multiple arrays with the same key into one array const bidirectionalEdges = jsonMerger.mergeObjects([edges['edges'], reversedEdges], {defaultArrayMergeOperation: "concat"}) //console.log(JSON.stringify(bidirectionalEdges,null,3)) return bidirectionalEdges } } /*********************************** Main Entry Point ************************************************/ const MSSQLConfiguration = { "DBMS": "MSSQL", "HOSTNAME": "localhost", "PORT": "1433", "USER": "sa", "PASSWORD": "PentaTech01", "DATABASE": "NorthWindDB", }; async function run() { const mssqlSchemaGraph = new MSSQLSchemaGraph(); const mssqlDatabaseDiscovery = new MSSQLDatabaseDiscovery(MSSQLConfiguration); const tableNames = await mssqlDatabaseDiscovery.getTableNames(); //Create a node by geting the combined extracedMSSQLSchema from each table //inside already build the schemas let extractedSchema = await mssqlDatabaseDiscovery.extractMSSQLSchema(tableNames); //console.log(JSON.stringify(extractedSchema,null,3)); let foreignKeys = await mssqlDatabaseDiscovery.getForeignKeyReferences(MSSQLConfiguration) //console.log(JSON.stringify(foreignKeys, null , 3)); //build the edges let edges = await mssqlSchemaGraph.buildEdges(foreignKeys) //console.log(JSON.stringify(edges,null,3)) //get the reverse edges let bidirectionalEdges = await mssqlSchemaGraph.generateBidirectionalEdges(edges) //console.log(JSON.stringify(bidirectionalEdges, null,3)) let nodesGraph = { nodes: [], edges: {} }; nodesGraph.nodes = extractedSchema; nodesGraph.edges = bidirectionalEdges //console.log(nodesGraph); console.log(JSON.stringify(nodesGraph, null , 3)); } //run()