/// <summary> /// Will create a new sync client using a custom IStorage as data backend. /// When using different IStorage backend, multiple instances of ISyncClient /// are allowed to exist simultaneously. /// </summary> public FilesystemSyncClient(Engine engine, SyncManifest manifest) { this.manifest = manifest; this.Engine = engine; this.DeletedNotes = new List<Note> (); }
public ManifestTracker (Engine engine, string path) { this.path = path; if (!File.Exists (path)) { Manifest = new SyncManifest (); using (var output = new FileStream (path, FileMode.Create)) { SyncManifest.Write (Manifest, output); } foreach (Note note in engine.GetNotes ().Values) { Manifest.NoteRevisions [note.Guid] = Manifest.LastSyncRevision + 1; } Flush (); } using (var input = new FileStream (path, FileMode.Open)) { this.Manifest = SyncManifest.Read (input); input.Close(); } engine.NoteAdded += (Note note) => { Console.WriteLine ("Note added"); Manifest.NoteRevisions [note.Guid] = Manifest.LastSyncRevision + 1; }; engine.NoteUpdated += (Note note) => { Console.WriteLine ("Note updated"); Manifest.NoteRevisions [note.Guid] = Manifest.LastSyncRevision + 1; }; engine.NoteRemoved += (Note note) => { Console.WriteLine ("Note removed: " + note.Guid); Manifest.NoteDeletions.Add (note.Guid, note.Title); }; }
public void SetUp() { var current_dir = Directory.GetCurrentDirectory (); serverStorageDir = Path.Combine (current_dir, "../../syncserver/"); serverStorage = new DiskStorage (serverStorageDir); serverEngine = new Engine (serverStorage); manifest = new SyncManifest (); syncServer = new FilesystemSyncServer (serverEngine, manifest); CreateSomeSampleNotes (); }
public FilesystemSyncServer(Engine engine, SyncManifest manifest) { this.engine = engine; this.manifest = manifest; // if not server id is set, set a new one if (string.IsNullOrEmpty (this.Id)) { this.Id = Guid.NewGuid ().ToString (); } newRevision = this.LatestRevision + 1; this.UploadedNotes = new List<Note> (); this.DeletedServerNotes = new List<string> (); }
public void ReadWriteEmptySyncManifest() { var empty_manifest = new SyncManifest (); // write the sample manifest to XML StringBuilder builder = new StringBuilder (); XmlWriter writer = XmlWriter.Create (builder); SyncManifest.Write (writer, empty_manifest); // read in the results var textreader = new StringReader (builder.ToString ()); var xmlreader = new XmlTextReader (textreader); var manifest = SyncManifest.Read (xmlreader); }
public void BenchmarkNoteStorage() { var local_storage = new DiskStorage ("../../tmpstorage"); var sample_notes = TestBase.GetSampleNotes (); var manifest = new SyncManifest (); var engine = new Engine (local_storage); sample_notes.ForEach(n => engine.SaveNote (n)); var sync_client = new FilesystemSyncClient (engine, manifest); var access_token = WebSyncServer.PerformFastTokenExchange (listenUrl, "testuser", "testpass"); var sync_server = new WebSyncServer (listenUrl, access_token); Action benchmark = () => new SyncManager (sync_client, sync_server).DoSync (); DbBenchmarks.RunBenchmark ("initial sync with 100 times no change at all", benchmark, 100); }
public DbStorage(IDbConnectionFactory factory, string username, bool use_history = true) { if (factory == null) throw new ArgumentNullException ("factory"); this.connFactory = factory; using (var dbu = connFactory.OpenDbConnection ()) { this.User = dbu.Select<DBUser> (u => u.Username == username)[0]; } this.Manifest = this.User.Manifest; this.UseHistory = use_history; db = factory.OpenDbConnection (); // start everything as a transaction trans = db.BeginTransaction (); }
public DbStorage(IDbConnectionFactory factory, string username, SyncManifest manifest, bool use_history = true) { if (factory == null) throw new ArgumentNullException ("factory"); this.connFactory = factory; if (string.IsNullOrEmpty (username)) this.Username = "******"; else this.Username = username; this.Manifest = manifest; this.UseHistory = use_history; db = factory.OpenDbConnection (); // start everything as a transaction trans = db.BeginTransaction (); }
private static void WriteNoteRevisions(XmlWriter xml, SyncManifest manifest) { xml.WriteStartElement (null, "note-revisions", null); foreach (var revision in manifest.NoteRevisions) { xml.WriteStartElement (null, "note", null); xml.WriteAttributeString ("guid", revision.Key); xml.WriteAttributeString ("latest-revision", revision.Value.ToString ()); xml.WriteEndElement (); } xml.WriteEndElement (); }
private static void WriteNoteDeletions(XmlWriter xml, SyncManifest manifest) { xml.WriteStartElement (null, "note-deletions", null); foreach (var deletion in manifest.NoteDeletions) { xml.WriteStartElement (null, "note", null); xml.WriteAttributeString ("guid", deletion.Key); xml.WriteAttributeString ("title", deletion.Value); xml.WriteEndElement (); } xml.WriteEndElement (); }
/// <summary> /// Write the specified manifest to an XmlWriter. /// </summary> public static void Write(XmlWriter xml, SyncManifest manifest) { xml.WriteStartDocument (); xml.WriteStartElement (null, "manifest", "http://beatniksoftware.com/tomboy"); xml.WriteAttributeString (null, "version", null, CURRENT_VERSION); if (manifest.LastSyncDate > DateTime.MinValue) { xml.WriteStartElement (null, "last-sync-date", null); xml.WriteString ( XmlConvert.ToString (manifest.LastSyncDate, Writer.DATE_TIME_FORMAT)); xml.WriteEndElement (); } xml.WriteStartElement (null, "last-sync-rev", null); xml.WriteString (manifest.LastSyncRevision.ToString ()); xml.WriteEndElement (); xml.WriteStartElement (null, "server-id", null); xml.WriteString (manifest.ServerId); xml.WriteEndElement (); WriteNoteRevisions (xml, manifest); WriteNoteDeletions (xml, manifest); xml.WriteEndDocument (); }
public static void Write(string path, SyncManifest manifest) { var settings = new XmlWriterSettings (); settings.Indent = true; settings.IndentChars = "\t"; XmlWriter writer = XmlWriter.Create (path, settings); Write (writer, manifest); writer.Close (); }
void VerifyManifestsAreTheSame(SyncManifest expected, SyncManifest actual) { Assert.AreEqual (expected.LastSyncDate, actual.LastSyncDate); Assert.AreEqual (expected.LastSyncRevision, actual.LastSyncRevision); Assert.AreEqual (expected.NoteRevisions.Count, actual.NoteRevisions.Count); foreach (var kvp in expected.NoteRevisions) { Assert.That (actual.NoteRevisions.ContainsKey (kvp.Key)); Assert.That (actual.NoteRevisions [kvp.Key] == kvp.Value); } foreach (var kvp in expected.NoteDeletions) { Assert.That (actual.NoteDeletions.ContainsKey (kvp.Key)); Assert.That (actual.NoteDeletions[kvp.Key] == kvp.Value); } }
/// <summary> /// Returns a XML string representation of the SyncManifest. /// </summary> /// <param name="manifest">Manifest.</param> public static string Write(SyncManifest manifest) { using (var ms = new MemoryStream ()) { using (var writer = new StreamWriter (ms, Encoding.UTF8)) { SyncManifest.Write (manifest, ms); ms.Position = 0; using (var reader = new StreamReader (ms, Encoding.UTF8)) { return reader.ReadToEnd(); } } } }
public void Setup() { var manifest = new SyncManifest (); manifest.LastSyncDate = DateTime.UtcNow - new TimeSpan (1, 0, 0); manifest.LastSyncRevision = 2; manifest.NoteRevisions.Add ("1234-5678-9012-3456", 4); manifest.NoteRevisions.Add ("1111-2222-3333-4444", 9293); manifest.NoteRevisions.Add ("6666-2222-3333-4444", 17); manifest.NoteDeletions.Add ("1111-11111-1111-1111", "Deleted note 1"); manifest.NoteDeletions.Add ("1111-11111-2222-2222", "Gelöschte Notiz 2"); sampleManifest = manifest; }
protected virtual void InitClientOne() { clientStorageOne = new DiskStorage (); clientStorageOne.SetPath (clientStorageDirOne); clientEngineOne = new Engine (clientStorageOne); clientManifestOne = new SyncManifest (); syncClientOne = new FilesystemSyncClient (clientEngineOne, clientManifestOne); }
protected void ClearClientTwo(bool reset = false) { if (reset) { clientManifestTwo = new SyncManifest (); CleanupClientDirectoryTwo (); } clientStorageTwo = new DiskStorage (); clientStorageTwo.SetPath (clientStorageDirTwo); clientEngineTwo = new Engine (clientStorageTwo); syncClientTwo = new FilesystemSyncClient (clientEngineTwo, clientManifestTwo); }
// forces re-readin from disk, and will make sure a client does not hold // Notes which are equal by reference as the server when using FilesystemSync protected void ClearClientOne(bool reset = false) { if (reset) { clientManifestOne = new SyncManifest (); CleanupClientDirectoryOne (); } clientStorageOne = new DiskStorage (); clientStorageOne.SetPath (clientStorageDirOne); clientEngineOne = new Engine (clientStorageOne); syncClientOne = new FilesystemSyncClient (clientEngineOne, clientManifestOne); }
private void InitServer() { serverStorage = new DiskStorage (); serverStorage.SetPath (serverStorageDir); serverEngine = new Engine (serverStorage); serverManifest = new SyncManifest (); syncServer = new FilesystemSyncServer (serverEngine, serverManifest); }
protected override void ClearServer(bool reset = false) { if (reset) { serverManifest = new SyncManifest (); CleanupServerDirectory (); } serverStorage = new DiskStorage (); serverStorage.SetPath (serverStorageDir); serverEngine = new Engine (serverStorage); syncServer = new FilesystemSyncServer (serverEngine, serverManifest); }
public DirectoryBasedNoteRepository(string username, string notes_base_path) { this.Username = username; this.notesBasePath = notes_base_path; lock (userLocks) { if (!userLocks.ContainsKey (Username)) userLocks [Username] = new Semaphore (1, 10); } // if another instance for this user exists, wait until it is freed userLocks [username].WaitOne (); storagePath = this.notesBasePath + "/" + Username; if (!Directory.Exists (storagePath)) { Directory.CreateDirectory (storagePath); } storage = new DiskStorage (); storage.SetPath (storagePath); Engine = new Engine (storage); // read in data from "manifest" file manifestPath = Path.Combine (storagePath, "manifest.xml"); if (File.Exists (manifestPath)) { string manifest_xml = File.ReadAllText (manifestPath); var textreader = new StringReader (manifest_xml); var xmlreader = new XmlTextReader (textreader); Manifest = SyncManifest.Read (xmlreader); } else { Manifest = new SyncManifest (); Manifest.ServerId = Guid.NewGuid ().ToString (); } }
/// <summary> /// Write the specified manifest to an ouput stream. /// </summary> public static void Write(SyncManifest manifest, Stream output) { var xdoc = new XDocument (); xdoc.Add (new XElement ("manifest", new XAttribute ("version", CURRENT_VERSION), new XElement ("last-sync-date", manifest.LastSyncDate.ToString (XmlSettings.DATE_TIME_FORMAT)), new XElement ("last-sync-rev", manifest.LastSyncRevision), new XElement ("server-id", manifest.ServerId) ) ); xdoc.Element ("manifest").Add (new XElement ("note-revisions", manifest.NoteRevisions.Select (r => { return new XElement ("note", new XAttribute ("guid", r.Key), new XAttribute ("latest-revision", r.Value) ); }) )); xdoc.Element ("manifest").Add (new XElement ("note-deletions", manifest.NoteDeletions.Select (d => { return new XElement ("note", new XAttribute ("guid", d.Key), new XAttribute ("title", d.Value) ); }) )); // this has to be performed at last.. xdoc.Root.SetDefaultXmlNamespace ("http://beatniksoftware.com/tomboy"); using (var writer = XmlWriter.Create (output, XmlSettings.DocumentSettings)) { xdoc.WriteTo (writer); } }
protected virtual void InitClientTwo() { clientManifestTwo = new SyncManifest (); clientStorageTwo = new DiskStorage (); clientStorageTwo.SetPath (clientStorageDirTwo); clientEngineTwo = new Engine (clientStorageTwo); syncClientTwo = new FilesystemSyncClient (clientEngineTwo, clientManifestTwo); }
public void Setup() { var manifest = new SyncManifest (); manifest.LastSyncDate = DateTime.UtcNow - new TimeSpan (1, 0, 0); manifest.LastSyncRevision = 2; manifest.NoteRevisions.Add ("1234-5678-9012-3456", 4); manifest.NoteRevisions.Add ("1111-2222-3333-4444", 9293); manifest.NoteRevisions.Add ("6666-2222-3333-4444", 17); manifest.NoteDeletions.Add ("1111-11111-1111-1111", "Deleted note 1"); manifest.NoteDeletions.Add ("1111-11111-2222-2222", "Gelöschte Notiz 2"); sampleManifest = manifest; tmpFilePath = Path.GetTempFileName (); Console.WriteLine ("using tmpFile: {0}", tmpFilePath); tmpSampleManifestPath = Path.GetTempFileName (); Console.WriteLine ("using tmpSampleManifestPath: {0}", tmpSampleManifestPath); using (var fs = File.OpenWrite (tmpSampleManifestPath)) { SyncManifest.Write (sampleManifest, fs); } }
/// <summary> /// Will create a new sync client, that uses the main Tomboy data storage /// as source. Note that since the main DiskStorage is static, only one /// FilesystemSyncClient using static storage may exist at a time, else /// expect race canditions. /// </summary> public FilesystemSyncClient(SyncManifest manifest) : this(new Engine (DiskStorage.Instance), manifest) { }
public static SyncManifest Read(XmlReader xml) { SyncManifest manifest = new SyncManifest (); string version = String.Empty; try { while (xml.Read ()) { switch (xml.NodeType) { case XmlNodeType.Element: switch (xml.Name) { case "manifest": version = xml.GetAttribute ("version"); break; case "server-id": // <text> is just a wrapper around <note-content> // NOTE: Use .text here to avoid triggering a save. manifest.ServerId = xml.ReadString (); break; case "last-sync-date": DateTime date; if (DateTime.TryParse (xml.ReadString (), out date)) manifest.LastSyncDate = date; else manifest.LastSyncDate = DateTime.UtcNow; break; case "last-sync-rev": int num; if (int.TryParse (xml.ReadString (), out num)) manifest.LastSyncRevision = num; break; case "note-revisions": xml.ReadToDescendant ("note"); do { var guid = xml.GetAttribute ("guid"); var xmlrev = xml.GetAttribute ("latest-revision"); if (guid != null && xmlrev != null) { int rev = int.Parse (xmlrev); manifest.NoteRevisions.Add (guid, rev); } else break; } while (xml.ReadToNextSibling ("note")); break; case "note-deletions": xml.ReadToDescendant ("note"); do { var guid = xml.GetAttribute ("guid"); string title = xml.GetAttribute ("title"); if (string.IsNullOrEmpty (title) || string.IsNullOrEmpty(guid)) break; else manifest.NoteDeletions.Add (guid, title); } while (xml.ReadToNextSibling ("note")); break; } break; } } } catch (XmlException) { //TODO: Log the error return null; } return manifest; }
public DBUser() { Manifest = new SyncManifest (); }
public static SyncManifest Read(Stream stream) { SyncManifest manifest = new SyncManifest (); try { var xdoc = XDocument.Load (stream); var elements = xdoc.Root.Elements ().ToList<XElement> (); string version = (from el in xdoc.Elements() where el.Name.LocalName == "manifest" select el.Attribute ("version").Value).Single (); if (version != CURRENT_VERSION) throw new TomboyException ("Syncmanifest is of unknown version"); manifest.LastSyncDate = (from el in elements where el.Name.LocalName == "last-sync-date" select DateTime.Parse (el.Value)).FirstOrDefault (); manifest.ServerId = (from el in elements where el.Name.LocalName == "server-id" select el.Value).Single(); manifest.LastSyncRevision = (from el in elements where el.Name.LocalName == "last-sync-rev" select long.Parse (el.Value)).Single (); var notes_for_deletion = from el in elements where el.Name.LocalName == "note-deletions" from note in el.Elements () let guid = (string) note.Attribute ("guid").Value let title = (string) note.Attribute ("title").Value select new KeyValuePair<string, string> (guid, title); foreach (var kvp in notes_for_deletion) manifest.NoteDeletions.Add (kvp); var notes_revisions = from el in elements where el.Name.LocalName == "note-revisions" from note in el.Elements() let guid = (string) note.Attribute ("guid").Value let revision = long.Parse (note.Attribute ("latest-revision").Value) select new KeyValuePair<string, long> (guid, revision); foreach (var kvp in notes_revisions) manifest.NoteRevisions.Add (kvp); return manifest; } catch (Exception e) { // TODO handle exception throw e; } }