Last active
July 19, 2017 18:27
-
-
Save mrcampbell/5de70f5c004e28846af47bbd1f286f66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace SyncableTest | |
{ | |
class MainClass | |
{ | |
/// <summary> | |
/// A common starting place for the Server and Local Database. This is | |
/// what was the copy that both shared exactly before we went offline. | |
/// </summary> | |
public List<Region> baseList = new List<Region>() { | |
new Region() { | |
ID = Guid.NewGuid(), | |
Name="Region #1", | |
CreatedOn = new DateTimeOffset(DateTime.Now.AddDays(-20)), | |
UpdatedOn = new DateTimeOffset(DateTime.Now.AddDays(-20))}, | |
new Region() { | |
ID = Guid.NewGuid(), | |
Name="Region #2", | |
CreatedOn = new DateTimeOffset(DateTime.Now.AddDays(-3)), | |
UpdatedOn = new DateTimeOffset(DateTime.Now.AddDays(-1))}, | |
new Region() { | |
ID = Guid.NewGuid(), | |
Name="Region That Was Updated Locally", | |
CreatedOn = new DateTimeOffset(DateTime.Now.AddDays(-14)), | |
UpdatedOn = new DateTimeOffset(DateTime.Now.AddDays(-3))}, | |
new Region() { | |
ID = Guid.NewGuid(), | |
Name="Region That Was Updated On The Server While We Were Offline", | |
CreatedOn = new DateTimeOffset(DateTime.Now.AddDays(-40)), | |
UpdatedOn = new DateTimeOffset(DateTime.Now.AddDays(-7))} | |
}; | |
/// <summary> | |
/// Represents a REST call to the server. Objects are modified and | |
/// created to simulate changes on Server since going offline. | |
/// </summary> | |
/// <returns>The Objects Per the Server's Database</returns> | |
private List<Region> TestListFromServer() | |
{ | |
List<Region> serverList = new List<Region>(); | |
// copy base before modifying | |
foreach (Region r in baseList) | |
{ | |
Region newR = new Region() | |
{ | |
ID = r.ID, | |
Name = r.Name, | |
CreatedOn = r.CreatedOn, | |
UpdatedOn = r.UpdatedOn | |
}; | |
serverList.Add(newR); | |
} | |
// simulate a server modification since we went offline | |
serverList.First(r => r.Name == "Region That Was Updated On The Server While We Were Offline") | |
.UpdatedOn = new DateTimeOffset(DateTime.Now.AddDays(-3)); | |
// simulate an object being created on the server while we were offline | |
serverList.Add( | |
new Region() | |
{ | |
ID = Guid.NewGuid(), | |
Name = "Region That Was Created While We Were Offline", | |
CreatedOn = new DateTimeOffset(DateTime.Now), | |
UpdatedOn = new DateTimeOffset(DateTime.Now) | |
} | |
); | |
return serverList; | |
} | |
/// <summary> | |
/// This represents a query from the local database. Objects are | |
/// modified and created to simulate changes Locally since going offline. | |
/// </summary> | |
/// <returns>The Objects Per the Local Database</returns> | |
private List<Region> TestListFromLocal() | |
{ | |
List<Region> localList = new List<Region>(); | |
// copy base before modifying | |
foreach (Region r in baseList) | |
{ | |
Region newR = new Region() | |
{ | |
ID = r.ID, | |
Name = r.Name, | |
CreatedOn = r.CreatedOn, | |
UpdatedOn = r.UpdatedOn | |
}; | |
localList.Add(newR); | |
} | |
// simulate a local modification | |
localList.First(r => r.Name == "Region That Was Updated Locally") | |
.UpdatedOn = new DateTimeOffset(DateTime.Now.AddDays(-1)); | |
DateTimeOffset createdOn = new DateTimeOffset(DateTime.Now.AddMinutes(-30)); | |
localList.Add( | |
new Region() | |
{ | |
ID = Guid.NewGuid(), | |
Name = "Region Created Locally", | |
CreatedOn = createdOn, | |
UpdatedOn = createdOn | |
} | |
); | |
return localList; | |
} | |
/// <summary> | |
/// Find and return all the objects that are in both lists, but has a | |
/// more recent UpdatedOn Date in the first list | |
/// </summary> | |
/// <param name="first"> | |
/// List of Objects that might have objects that have been updated since last sync | |
/// </param> | |
/// <param name="second"> | |
/// List of Objects that might have objects that are stale | |
/// </param> | |
private void GetObjectsToBeUpdatedInSecondListFromFirst(List<Region> first, List<Region> second) | |
{ | |
// get the objects where ID's match, but the UpDatedOn's Don't. | |
List<Region> diff = first.Where(f => second.Any(s => f.ID == s.ID && f.UpdatedOn > s.UpdatedOn)).ToList(); | |
foreach (Region x in diff) | |
{ | |
Console.WriteLine(x); | |
} | |
} | |
/// <summary> | |
/// Find and return all the objects that are unique to the first list | |
/// (present in the first list, and not in the second list) | |
/// </summary> | |
/// <param name="first"> | |
/// List of Objects that may have objects not in Second List | |
/// </param> | |
/// <param name="second"> | |
/// List of Objects that may be missing objects found in First List | |
/// </param> | |
private void GetObjecstToBeCreatedInSecondListFromFirst(List<Region> first, List<Region> second) | |
{ | |
// add the objecst where the ID is not found in the second list | |
List<Region> diff = first.Where(f => !second.Any(s => s.ID == f.ID)).ToList(); | |
foreach (Region x in diff) | |
{ | |
Console.WriteLine(x); | |
} | |
} | |
/// <summary> | |
/// This is the Heart of the sync function. This only displays the differences, | |
/// but in a real setting, it would also issue the commands to update locally and remotely | |
/// </summary> | |
private void SyncRegions() | |
{ | |
List<Region> fromServer = TestListFromServer(); | |
List<Region> fromLocal = TestListFromLocal(); | |
Console.WriteLine("Base List"); | |
foreach(Region r in baseList) | |
{ | |
Console.WriteLine(r); | |
} | |
Console.WriteLine("\nObjects to be Updated on Server from Local"); | |
GetObjectsToBeUpdatedInSecondListFromFirst(fromLocal, fromServer); | |
Console.WriteLine("\nObjects not on Server but on Local"); | |
GetObjecstToBeCreatedInSecondListFromFirst(fromLocal, fromServer); | |
Console.WriteLine("\nObjects to be Updated on Local from Server"); | |
GetObjectsToBeUpdatedInSecondListFromFirst(fromServer, fromLocal); | |
Console.WriteLine("\nObjects not on Local but on Server"); | |
GetObjecstToBeCreatedInSecondListFromFirst(fromServer, fromLocal); | |
} | |
/// <summary> | |
/// A Syncable Version of the Region object found in Redlist.Entities.Core | |
/// </summary> | |
public class Region : SyncableObject | |
{ | |
public string Name { get; set; } | |
public override string ToString() | |
{ | |
return string.Format("[Region: \n ID={0}, \n Name={1}, \n CreatedOn={2}, \n UpdatedOn={3}]", ID, Name, CreatedOn, UpdatedOn); | |
} | |
} | |
// A basic, Syncable object | |
public abstract class SyncableObject | |
{ | |
public Guid ID { get; set; } | |
public DateTimeOffset CreatedOn { get; set; } | |
public DateTimeOffset UpdatedOn { get; set; } | |
public override string ToString() | |
{ | |
return string.Format("[SyncableObject: ID={0}, CreatedOn={1}, UpdatedOn={2}]", ID, CreatedOn, UpdatedOn); | |
} | |
} | |
/// <summary> | |
/// The entry point of the program, where the program control starts and ends. | |
/// </summary> | |
/// <param name="args">The command-line arguments.</param> | |
public static void Main(string[] args) | |
{ | |
MainClass main = new MainClass(); | |
main.SyncRegions(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment