public void TestQueryLocationChanges() { AddPrincipalToThread(); AnnotateService target = new AnnotateService(Parameters.TestDatabaseName); // TODO: Initialize to an appropriate value //Create a structure type, a structure, and some links StructureType t = CreatePopulatedStructureType("Test"); long[] IDs = target.UpdateStructureTypes(new StructureType[] { t }); long StructureTypeID = IDs[0]; //Create structure and location Structure newStruct = new Structure(); newStruct.TypeID = StructureTypeID; Location newPos = new Location(); newPos.ParentID = newStruct.ID; AnnotationPoint P = new AnnotationPoint(); P.X = 0; P.Y = 0; P.Z = 0; newPos.Position = P; CreateStructureRetval retval = target.CreateStructure(newStruct, newPos); long StructureID = retval.structure.ID; long LocationAID = retval.location.ID; //Create a second location for the structure Location B = new Location(); B.ParentID = StructureID; P.Z = 0; B.Position = P; B.DBAction = DBACTION.INSERT; IDs = target.Update(new Location[] { B }); long LocationBID = IDs[0]; //Query the locations Location[] Locations = target.GetLocationsForStructure(StructureID); Assert.IsTrue(Locations.Length == 2); //Create a third location for the structure Location C = new Location(); C.ParentID = StructureID; P.Z = 0; C.Position = P; C.DBAction = DBACTION.INSERT; IDs = target.Update(new Location[] { C }); long LocationCID = IDs[0]; //Query all the structures Location LocationA = target.GetLocationByID(LocationAID); Location LocationB = target.GetLocationByID(LocationBID); Location LocationC = target.GetLocationByID(LocationCID); DateTime UpdateTime = new DateTime(LocationC.LastModified, DateTimeKind.Utc); // UpdateTime = UpdateTime.Subtract(new TimeSpan(TimeSpan.TicksPerMillisecond)); //The server only returns changes after the query System.Diagnostics.Debug.WriteLine("UpdateTime: " + UpdateTime.ToFileTime().ToString()); //Check that location C appears when we ask for locations modified after the updatetime long[] deletedIDs; long queryTimeInTicks; Location[] updatedLocations = target.GetLocationChanges(LocationA.Section, UpdateTime.Ticks, out queryTimeInTicks, out deletedIDs); //Nothing was deleted, so this should be true foreach (long id in deletedIDs) { Assert.IsTrue(id != LocationAID, "Found undeleted ID in deleted list"); Assert.IsTrue(id != LocationBID, "Found undeleted ID in deleted list"); Assert.IsTrue(id != LocationCID, "Found undeleted ID in deleted list"); } //Other people could be changing the database, so check the LocationC is in the array, but not A or B bool CFound = false; foreach(Location loc in updatedLocations) { Assert.IsTrue(loc.ID != LocationAID && loc.ID != LocationBID); if (loc.ID == LocationCID) CFound = true; } Assert.IsTrue(CFound, "Could not find location C"); //This will only be true if the test is run on the server UpdateTime = new DateTime(queryTimeInTicks, DateTimeKind.Utc); System.Diagnostics.Debug.WriteLine("UpdateTime: " + UpdateTime.ToFileTime().ToString()); //Delete location B, and check that it shows up in the deleted IDs LocationB.DBAction = DBACTION.DELETE; target.Update(new Location[] { LocationA, LocationB, LocationC }); //Just so I don't reference it again. LocationB = null; updatedLocations = target.GetLocationChanges(LocationA.Section, UpdateTime.Ticks, out queryTimeInTicks, out deletedIDs); //B was deleted, so make sure it is in the results bool BFound = false; foreach (long id in deletedIDs) { if (id == LocationBID) BFound = true; Assert.IsTrue(id != LocationAID); Assert.IsTrue(id != LocationCID); } Assert.IsTrue(BFound); //Other people could be changing the database, so check that neither A or C is in the updated array foreach (Location loc in updatedLocations) { Assert.IsTrue(loc.ID != LocationAID && loc.ID != LocationCID); } //Update A location and delete C LocationA.OffEdge = true; LocationA.DBAction = DBACTION.UPDATE; LocationC.DBAction = DBACTION.DELETE; target.Update(new Location[] { LocationA, LocationC }); LocationC = null; LocationA = target.GetLocationByID(LocationAID); UpdateTime = new DateTime(LocationA.LastModified, DateTimeKind.Utc); // UpdateTime = UpdateTime.Subtract(new TimeSpan(TimeSpan.TicksPerMillisecond)); //The server only returns changes after the query System.Diagnostics.Debug.WriteLine("UpdateTime: " + LocationA.LastModified.ToString()); updatedLocations = target.GetLocationChanges(LocationA.Section, UpdateTime.Ticks, out queryTimeInTicks, out deletedIDs); //Check to see that we find location C in deletedIDs and LocationA in the updated set //Other people could be changing the database, so check the LocationC is in the array, but not A or B bool AFound = false; foreach (Location loc in updatedLocations) { Assert.IsTrue(loc.ID != LocationBID && loc.ID != LocationCID); if (loc.ID == LocationAID) AFound = true; } Assert.IsTrue(AFound, "Could not find changed row in GetLocationChanges"); //C was deleted, so make sure it is in the results CFound = false; foreach (long id in deletedIDs) { if (id == LocationCID) CFound = true; Assert.IsTrue(id != LocationAID); Assert.IsTrue(id != LocationBID); } Assert.IsTrue(CFound); //Wrap up, delete A LocationA.DBAction = DBACTION.DELETE; target.Update(new Location[] { LocationA }); //Delete the structure newStruct = target.GetStructureByID(StructureID, false); newStruct.DBAction = DBACTION.DELETE; target.UpdateStructures(new Structure[] { newStruct }); //Delete the structure type t = target.GetStructureTypeByID(StructureTypeID); t.DBAction = DBACTION.DELETE; target.UpdateStructureTypes(new StructureType[] { t }); }