protected virtual void ReadRecordField(DictionaryState state, TableDescriber table, FieldDefinition fieldDefinition, string[] fields) { if (fieldDefinition.StartPosition >= fields.Length) { if (fieldDefinition.IsOptional) return; throw new MessagingException("Message does not match definition. Too few fields in current record."); } if (fields[fieldDefinition.StartPosition].StartsWith("\"") && fields[fieldDefinition.StartPosition].EndsWith("\"")) // Remove quotes { fields[fieldDefinition.StartPosition] = fields[fieldDefinition.StartPosition].Substring(1, fields[fieldDefinition.StartPosition].Length - 2); } var describer = new ColumnDescriber(fieldDefinition.Name, table); if (fieldDefinition.Type.IsIn(FieldDefinitionType.DateTime)) { state[describer] = DateTime.ParseExact(fields[fieldDefinition.StartPosition].Trim('"'), fieldDefinition.Format, CultureInfo.InvariantCulture); } else if (fieldDefinition.Type.IsIn(FieldDefinitionType.Amount, FieldDefinitionType.InvertedAmount, FieldDefinitionType.Decimal)) { object oldvalue; decimal oldAmount = state.TryGetValue(describer, out oldvalue) && oldvalue is decimal ? (decimal) oldvalue : 0; decimal amount = !string.IsNullOrWhiteSpace(fields[fieldDefinition.StartPosition].Trim('"')) ? Decimal.Parse(fields[fieldDefinition.StartPosition].Trim('"'), fieldDefinition.Format.IsNullOrEmpty() ? CultureInfo.InvariantCulture : new CultureInfo(fieldDefinition.Format)) : 0; if (fieldDefinition.Type == FieldDefinitionType.InvertedAmount) amount *= -1; state[describer] = oldAmount + amount; } else if (fieldDefinition.Type == FieldDefinitionType.AmountSign) { if (IsNegativeAmountSign(fields[fieldDefinition.StartPosition], fieldDefinition)) { state[describer] = Decimal.Negate(((decimal)state[describer])); } } else { object oldvalue; state[describer] = state.TryGetValue(describer, out oldvalue) ? oldvalue + " " + fields[fieldDefinition.StartPosition] : fields[fieldDefinition.StartPosition]; } }
private static Record CreateRecord(MessageDefinition definition, XElement element) { RecordDefinition recordDef = definition.FindRecord(element.Name.LocalName); TableDescriber table = new TableDescriber(recordDef.Name, DataSources.NoSource); Record record = recordDef.Create(new DictionaryState()); record.State.Set(new ColumnDescriber("ID", table, isIdentity: true), Guid.NewGuid()); foreach (XElement subelement in element.Elements()) { FieldDefinition fieldDef = recordDef.FindField(subelement.Name.LocalName); if (fieldDef.Type == FieldDefinitionType.Record) { RecordDefinition subRecordDef = definition.FindRecord(subelement.Name.LocalName); if (subRecordDef.Repeats > 1 || subRecordDef.Repeats == -1) { // This element appears more than once List<Record> existing = record.State.Get<List<Record>>(new ColumnDescriber(fieldDef.Name, recordDef.Name)) ?? new List<Record>(); // If not initialized, do so now existing.Add(CreateRecord(definition, subelement)); record.State.Set(new ColumnDescriber(fieldDef.Name, recordDef.Name), existing); } else { Record value = CreateRecord(definition, subelement); record.State.Set(new ColumnDescriber(fieldDef.Name, recordDef.Name), value); } } else { record.State.Set(new ColumnDescriber(fieldDef.Name, recordDef.Name), subelement.Value); } } return record; }
private IEnumerable<Record> BreakIntoRecords(MessageDefinition definition, StreamReader reader) { var currentLine = 1; var currentRecord = string.Empty; try { var records = new List<Record>(); var recordDefinition = definition.Records[0]; var table = new TableDescriber(recordDefinition.Name, DataSources.NoSource); var line = reader.ReadLine(); if (definition.HasHeader) line = reader.ReadLine(); string seperator = recordDefinition.FieldSeparator.Length == 1 ? string.Format(@"(?<=^(?:[^""]*""[^""]*"")*[^""]*){0}", recordDefinition.FieldSeparator) : recordDefinition.FieldSeparator; Regex seperatorRegex = recordDefinition.FieldSeparator.Length == 1 ? new Regex(seperator, RegexOptions.Compiled) : null; while (line != null) { string[] fields = seperatorRegex != null ? seperatorRegex.Split(line) : line.Split(new[] { recordDefinition.FieldSeparator }, StringSplitOptions.None); var state = new DictionaryState { IsNew = true }; if (!recordDefinition.Fields.Exists(f => f.Name.Equals("ID", StringComparison.OrdinalIgnoreCase))) { state[new ColumnDescriber("ID", table, isIdentity: true)] = Guid.NewGuid(); } state[new ColumnDescriber("TimeStamp", table, isTimestamp: true)] = null; foreach (var fieldDefinition in recordDefinition.Fields) { currentRecord = fieldDefinition.Name; ReadRecordField(state, table, fieldDefinition, fields); } records.Add(recordDefinition.Create(state)); line = reader.ReadLine(); currentLine++; currentRecord = string.Empty; } return records; } catch (FormatException exception) { throw new MessagingException(string.Format("Unknown message format. Line {1}, field {2}. {0}", exception.Message, currentLine, currentRecord), exception); } }
private IInternalState CreateState(IAdfQuery query, SqlDataReader reader = null) { var state = new DictionaryState { IsNew = true }; if (reader != null) { var schema = reader.GetSchemaTable(); if (schema == null) throw new InvalidOperationException("could not load schema"); var table = new TableDescriber(query.Tables[0].Name, DataSource); for (int i = 0; i < reader.VisibleFieldCount; i++) { var column = new ColumnDescriber(reader.GetName(i), table, isIdentity: (bool) schema.Rows[i]["IsKey"], isAutoIncrement: (bool) schema.Rows[i]["IsAutoIncrement"], isTimestamp: (bool) schema.Rows[i]["IsRowVersion"]); if (reader.HasRows) { var value = reader[i]; if (value == DBNull.Value) value = null; state[column] = value; state.IsNew = false; } else { state[column] = null; // just add column info } } } // if (reader != null && reader.HasRows && state.Timestamp == null) throw new InvalidOperationException("Row has no Timestamp field"); return state; }