public override Value GetTag(string tag, bool inherit = true) { Value value = base.GetTag(tag, inherit); if (!Value.IsNullOrEmpty(value)) { return(value); } if (inherit && Xact != null) { return(Xact.GetTag(tag)); } return(Value.Empty); }
public bool AddXact(Xact xact) { if (xact == null) { throw new ArgumentNullException("xact"); } xact.Journal = this; if (!xact.FinalizeXact()) { xact.Journal = null; return(false); } ExtendXact(xact); CheckAllMetadata(xact); foreach (Post post in xact.Posts) { Post.ExtendPost(post, this); CheckAllMetadata(post); } // If a transaction with this UUID has already been seen, simply do // not add this one to the journal. However, all automated checks // will have been performed by extend_xact, so asserts can still be // applied to it. Value refVal = xact.GetTag("UUID"); if (!Value.IsNullOrEmpty(refVal)) { string uuid = refVal.AsString; if (ChecksumMapping.ContainsKey(uuid)) { // This UUID has been seen before; apply any postings which the // earlier version may have deferred. foreach (Post post in xact.Posts) { Account acct = post.Account; IEnumerable <Post> deferredPosts = acct.GetDeferredPosts(uuid); if (deferredPosts != null) { foreach (Post rpost in deferredPosts) { if (acct == rpost.Account) { acct.AddPost(rpost); } } acct.DeleteDeferredPosts(uuid); } } Xact other = ChecksumMapping[uuid]; // Copy the two lists of postings (which should be relatively // short), and make sure that the intersection is the empty set // (i.e., that they are the same list). IEnumerable <Post> thisPosts = xact.Posts.OrderBy(p => p.Account.FullName); IEnumerable <Post> otherPosts = other.Posts.OrderBy(p => p.Account.FullName); bool match = !thisPosts.Except(otherPosts, EquivalentPostingComparer.Current).Any(); if (!match || thisPosts.Count() != otherPosts.Count()) { ErrorContext.Current.AddErrorContext("While comparing this previously seen transaction:"); ErrorContext.Current.AddErrorContext(ErrorContext.SourceContext(other.Pos.PathName, other.Pos.BegPos, other.Pos.EndPos, "> ")); ErrorContext.Current.AddErrorContext("to this later transaction:"); ErrorContext.Current.AddErrorContext(ErrorContext.SourceContext(xact.Pos.PathName, xact.Pos.BegPos, xact.Pos.EndPos, "> ")); throw new RuntimeError(RuntimeError.ErrorMessageTransactionsWithTheSameUUIDmustHaveEquivalentPostings); } xact.Journal = null; return(false); } else { ChecksumMapping.Add(uuid, xact); } } Xacts.Add(xact); return(true); }