public void CopyEntry() { Entry entry = new Entry(); entry.Initialize(); Entry same = entry; Assert.AreSame(entry, same); Entry copy = entry.Clone(); bool equals = entry.Equals(copy); Assert.IsTrue(!equals); }
EntrySaveState IBlogDataService.SaveEntry(Entry entry, params object[] trackingInfos) { bool found = false; if (entry.EntryId == null || entry.EntryId.Length == 0) return EntrySaveState.Failed; DayEntry day = InternalGetDayEntry(entry.CreatedUtc.Date); Entry currentEntry = day.Entries[entry.EntryId]; // OmarS: now that all the entries are returned from a cache, and not desrialized // for each request, users who call GetEntry() will get the current entry in the runtime. // That entry can be modified freely, and changes will not be commited till day.Save() // is called. However, since they have made changes, and passed in that entry, currentEntry // and entry are the same objects (reference the same object) and now the changes are in the day // but they haven't been saved. This can cause weird problems, and the runtime may have data // that is not commited, and it will be lost if day.Save() is never called. if (entry == null) { throw new ArgumentNullException("Entry is null"); } if (entry.Equals(currentEntry)) { throw new ArgumentException("You have modified an existing entry and are passing that in. You need to call GetEntryForEdit to get a copy of the entry before modifying it"); } //There's a possibility that they've changed the CreatedLocalTime of the entry // which means it CURRENTLY lives in one DayEntry file but will soon live in another. // We need to find the old version, if it exists, and if the CreatedLocalTime is different // than the one being saved now, blow it away. Entry originalEntry = this.InternalGetEntry(entry.EntryId); DayExtra originalExtra = null; //Get the comments and trackings for the original entry CommentCollection originalComments = null; TrackingCollection originalTrackings = null; //If we found the original and they DID change the CreatedLocalTime if (currentEntry == null && originalEntry != null && originalEntry.CreatedLocalTime != entry.CreatedLocalTime) { //get the comments and trackings originalExtra = data.GetDayExtra(originalEntry.CreatedUtc.Date); if (originalExtra != null) { originalComments = originalExtra.GetCommentsFor(originalEntry.EntryId, data); originalTrackings = originalExtra.GetTrackingsFor(originalEntry.EntryId, data); //O^n slow... foreach (Comment c in originalComments) { originalExtra.Comments.Remove(c); } //O^n slow...be nice if they were hashed foreach (Tracking t in originalTrackings) { originalExtra.Trackings.Remove(t); } originalExtra.Save(data); } //Get that original's day and delete the entry DayEntry originalDay = InternalGetDayEntry(originalEntry.CreatedUtc.Date); originalDay.Entries.Remove(originalEntry); originalDay.Save(data); } // we need to check to see if the two objects are equal so that we avoid trasing // data like Crossposts.Clear() which will remove the crosspostInfo from both entries if (currentEntry != null && !currentEntry.Equals(entry)) { // we will only change the mod date if there has been a change to a few things if (currentEntry.CompareTo(entry) == 1) { currentEntry.ModifiedUtc = DateTime.Now.ToUniversalTime(); } currentEntry.Categories = entry.Categories; currentEntry.Syndicated = entry.Syndicated; currentEntry.Content = entry.Content; currentEntry.CreatedUtc = entry.CreatedUtc; currentEntry.Description = entry.Description; currentEntry.anyAttributes = entry.anyAttributes; currentEntry.anyElements = entry.anyElements; currentEntry.Author = entry.Author; currentEntry.IsPublic = entry.IsPublic; currentEntry.Language = entry.Language; currentEntry.AllowComments = entry.AllowComments; currentEntry.Link = entry.Link; currentEntry.ShowOnFrontPage = entry.ShowOnFrontPage; currentEntry.Title = entry.Title; currentEntry.Latitude = entry.Latitude; currentEntry.Longitude = entry.Longitude; currentEntry.Crossposts.Clear(); currentEntry.Crossposts.AddRange(entry.Crossposts); currentEntry.Attachments.Clear(); currentEntry.Attachments.AddRange(entry.Attachments); day.Save(data); data.lastEntryUpdate = currentEntry.ModifiedUtc; data.IncrementEntryChange(); found = true; } else { day.Entries.Add(entry); day.Save(data); data.lastEntryUpdate = entry.CreatedUtc; data.IncrementEntryChange(); found = false; } //Now, move the comments and trackings to the new Date if (originalEntry != null && originalComments != null && originalExtra != null) { DayExtra newExtra = data.GetDayExtra(entry.CreatedUtc.Date); newExtra.Comments.AddRange(originalComments); newExtra.Trackings.AddRange(originalTrackings); newExtra.Save(data); } if (trackingInfos != null && entry.IsPublic) { foreach (object trackingInfo in trackingInfos) { if (trackingInfo != null) { if (trackingInfo is WeblogUpdatePingInfo) { ThreadPool.QueueUserWorkItem( new WaitCallback(this.PingWeblogsWorker), (WeblogUpdatePingInfo)trackingInfo); } else if (trackingInfo is PingbackInfo) { PingbackJob pingbackJob = new PingbackJob((PingbackInfo)trackingInfo, entry); ThreadPool.QueueUserWorkItem( new WaitCallback(this.PingbackWorker), pingbackJob); } else if (trackingInfo is PingbackInfoCollection) { PingbackInfoCollection pic = trackingInfo as PingbackInfoCollection; foreach (PingbackInfo pi in pic) { PingbackJob pingbackJob = new PingbackJob(pi, entry); ThreadPool.QueueUserWorkItem( new WaitCallback(this.PingbackWorker), pingbackJob); } } else if (trackingInfo is TrackbackInfo) { ThreadPool.QueueUserWorkItem( new WaitCallback(this.TrackbackWorker), new TrackbackJob((TrackbackInfo)trackingInfo, entry)); } else if (trackingInfo is TrackbackInfoCollection) { TrackbackInfoCollection tic = trackingInfo as TrackbackInfoCollection; foreach (TrackbackInfo ti in tic) { ThreadPool.QueueUserWorkItem( new WaitCallback(this.TrackbackWorker), new TrackbackJob(ti, entry)); } } else if (trackingInfo is CrosspostInfo || trackingInfo is CrosspostInfoCollection) { ThreadPool.QueueUserWorkItem( new WaitCallback(this.CrosspostWorker), new CrosspostJob(trackingInfo, entry, this)); } } } } return found ? EntrySaveState.Updated : EntrySaveState.Added; }