/// <summary> /// /// </summary> /// <param name="attrNames">Index - attribute names</param> /// <param name="absolute">Sequence must be the same if absolute is true</param> /// <returns></returns> public bool Match(string[] attrNames, bool absolute) { if (Index.Length == 0 || attrNames.Length != Index.Length) { return(false); } else { if (absolute) { for (int i = 0; i < attrNames.Length; i++) { if (string.Compare(Index[i].Name, attrNames[i], true) != 0) { return(false); } } return(true); } else { int count = 0; foreach (string name in attrNames) { if (Index.Any(_ => string.Compare(_.Name, name, true) == 0)) { count++; } } return(count == attrNames.Length); } } }
public void IndexWriteRead() { var originalIndex = new Index(Enumerable.Range(0, 1000).Select(i => new IndexEntry { OriginalPosition = i, CompressedChunk = new ChunkDescriptor { Size = i * 2, Position = i * 3 } }).ToList()); var tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".tmp"); File.Create(tempFile).Close(); originalIndex.WriteToFile(tempFile); var indexFromFile = Index.ReadFromFile(tempFile); foreach (var indexEntry in indexFromFile) { Assert.IsTrue(originalIndex.Any(i => i.OriginalPosition == indexEntry.OriginalPosition && i.CompressedChunk.Size == indexEntry.CompressedChunk.Size && i.CompressedChunk.Position == indexEntry.CompressedChunk.Position && i.ToByteArray().SequenceEqual(indexEntry.ToByteArray()))); } foreach (var indexEntry in originalIndex) { Assert.IsTrue(indexFromFile.Any(i => i.OriginalPosition == indexEntry.OriginalPosition && i.CompressedChunk.Size == indexEntry.CompressedChunk.Size && i.CompressedChunk.Position == indexEntry.CompressedChunk.Position && i.ToByteArray().SequenceEqual(indexEntry.ToByteArray()))); } File.Delete(tempFile); }
public Xact ReadXact(bool richData) { string line = NextLine(Context.Reader); string origLine = line; if (String.IsNullOrEmpty(line) || !Index.Any()) { return(null); } Context.LineNum++; Xact xact = new Xact(); Post post = new Post(); xact.State = ItemStateEnum.Cleared; xact.Pos = new ItemPosition() { PathName = Context.PathName, BegPos = (int)Context.Reader.Position, BegLine = Context.LineNum, Sequence = Context.Sequence++ }; post.Xact = xact; post.Pos = new ItemPosition() { PathName = Context.PathName, BegPos = (int)Context.Reader.Position, BegLine = Context.LineNum, Sequence = Context.Sequence++ }; post.State = ItemStateEnum.Cleared; post.Account = null; int n = 0; Amount amt = null; string total = null; string field; while (!String.IsNullOrEmpty(line) && n < Index.Count) { field = ReadField(ref line); switch (Index[n]) { case CsvHeadersEnum.FIELD_DATE: xact.Date = TimesCommon.Current.ParseDate(field); break; case CsvHeadersEnum.FIELD_DATE_AUX: if (!String.IsNullOrEmpty(field)) { xact.DateAux = TimesCommon.Current.ParseDate(field); } break; case CsvHeadersEnum.FIELD_CODE: if (!String.IsNullOrEmpty(field)) { xact.Code = field; } break; case CsvHeadersEnum.FIELD_PAYEE: { bool found = false; foreach (Tuple <Mask, string> value in Context.Journal.PayeeAliasMappings) { Logger.Current.Debug("csv.mappings", () => String.Format("Looking for payee mapping: {0}", value.Item1)); if (value.Item1.Match(field)) { xact.Payee = value.Item2; found = true; break; } } if (!found) { xact.Payee = field; } break; } case CsvHeadersEnum.FIELD_AMOUNT: { amt = new Amount(); amt.Parse(ref field, AmountParseFlagsEnum.PARSE_NO_REDUCE); if (!amt.HasCommodity && CommodityPool.Current.DefaultCommodity != null) { amt.SetCommodity(CommodityPool.Current.DefaultCommodity); } post.Amount = amt; break; } case CsvHeadersEnum.FIELD_COST: { amt = new Amount(); amt.Parse(ref field, AmountParseFlagsEnum.PARSE_NO_REDUCE); if (!amt.HasCommodity && CommodityPool.Current.DefaultCommodity != null) { amt.SetCommodity(CommodityPool.Current.DefaultCommodity); } post.Cost = amt; break; } case CsvHeadersEnum.FIELD_TOTAL: total = field; break; case CsvHeadersEnum.FIELD_NOTE: if (!String.IsNullOrEmpty(field)) { xact.Note = field; } break; case CsvHeadersEnum.FIELD_UNKNOWN: if (!String.IsNullOrEmpty(Names[n]) && !String.IsNullOrEmpty(field)) { xact.SetTag(Names[n], Value.StringValue(field)); } break; default: throw new InvalidOperationException(); } n++; } if (richData) { xact.SetTag("Imported", Value.StringValue(TimesCommon.Current.FormatDate(TimesCommon.Current.CurrentDate, FormatTypeEnum.FMT_WRITTEN).ToString())); xact.SetTag("CSV", Value.StringValue(origLine)); } // Translate the account name, if we have enough information to do so foreach (Tuple <Mask, Account> value in Context.Journal.PayeesForUnknownAccounts) { if (value.Item1.Match(xact.Payee)) { post.Account = value.Item2; break; } } xact.AddPost(post); // Create the "balancing post", which refers to the account for this data post = new Post(); post.Xact = xact; post.Pos = new ItemPosition() { PathName = Context.PathName, BegPos = (int)Context.Reader.Position, BegLine = Context.LineNum, Sequence = Context.Sequence++ }; post.State = ItemStateEnum.Cleared; post.Account = Context.Master; if (amt != null && !amt.IsEmpty) { post.Amount = amt.Negated(); } if (!String.IsNullOrEmpty(total)) { amt = new Amount(); amt.Parse(ref total, AmountParseFlagsEnum.PARSE_NO_REDUCE); if (!amt.HasCommodity && CommodityPool.Current.DefaultCommodity != null) { amt.SetCommodity(CommodityPool.Current.DefaultCommodity); } post.AssignedAmount = amt; } xact.AddPost(post); return(xact); }