// Used by UI, returns fully initialized DatabaseObjectsGraph public DatabaseObjectsGraph LoadState() { int[][] jaggedArray; DatabaseObject[] symbolTable; // Load using (var ctx = new DependencyGraphContext(_connectionString)) { var vertices = ctx.DatabaseObjectVertices.ToList(); jaggedArray = new int[vertices.Count()][]; for (int i = 0; i < jaggedArray.Length; i++) { var json = vertices[i].AdjacencyListJson; int[] adjencencyList = JsonConvert.DeserializeObject <int[]>(json); jaggedArray[i] = adjencencyList; } symbolTable = GetDatabaseObjectsInternal(ctx); } var g = new Digraph(new Memento <int[][]>(jaggedArray)); var dg = new DatabaseObjectsGraph(new Memento <DatabaseObject[]>(symbolTable), g); return(dg); }
public DatabaseObjectGraphCollector(string targetConnectionString, string repositoryConnectionString, ILogger logger) { _databaseCollector = new DatabaseCollector(targetConnectionString); _repository = new DatabaseObjectsGraphRepository(repositoryConnectionString); // We want graph with pre-initialized database objects / symbol table because we don't want to overwrite existing objects properties or create duplicated objects. _graph = _repository.LoadState(); _logger = logger; }
// SaveState wipes out graph but keeps DatabaseObjects because: // TODO: We could try updating modified vertices only. public void SaveState(DatabaseObjectsGraph dg) { DatabaseObject[] symbolTable = dg.CreateMemento().State; int[][] jaggedArray = dg.Digraph.CreateMemento().State; // Save using (var ctx = new DependencyGraphContext(_connectionString)) { ctx.Database.ExecuteSqlCommand("TRUNCATE TABLE DatabaseObjectsGraph;"); foreach (var databaseObject in symbolTable) { switch (databaseObject.ObjectState) { case ObjectState.VertexAdded: var sqlStorageDatabaseObject = _engine.Map <SqlStorage.DatabaseObject>(databaseObject); ctx.DatabaseObjects.Add(sqlStorageDatabaseObject); break; case ObjectState.PropertiesModified: // Properties can be addedd, deleted or change values var objectInDatabase = ctx.DatabaseObjects.SingleOrDefault(f => f.FullyQualifiedName == databaseObject.FullyQualifiedName); if (objectInDatabase == null) { // We can't add a property to an object that hasn't been saved yet. throw new ArgumentException(nameof(objectInDatabase)); } objectInDatabase.Properties.Clear(); foreach (var property in databaseObject.Properties) { objectInDatabase.Properties.Add(DatabaseObjectConverter.Convert(property)); } ctx.Entry(objectInDatabase).State = EntityState.Modified; break; } } for (int i = 0; i < jaggedArray.Length; i++) { var json = JsonConvert.SerializeObject(jaggedArray[i]); ctx.DatabaseObjectVertices.Add(new DatabaseObjectVertex() { VertexId = i, AdjacencyListJson = json }); } ctx.SaveChanges(); } }