public void SerializeSegmentSet() { SegmentSet set = new SegmentSet { Name = "4010" }; SegmentSpecification isa = new SegmentSpecification { SegmentId = "ISA" }; set.Segments.Add(isa); isa.Elements.Add(new ElementSpecification { Name = "Author Info Qualifier", Required = true, MinLength = 2, MaxLength = 2, Type = ElementDataTypeEnum.Identifier }); string xml = set.Serialize(); Trace.Write(xml); SegmentSet copy = SegmentSet.Deserialize(xml); SegmentSpecification isaCopy = copy.Segments.FirstOrDefault(s => s.SegmentId == "ISA"); Assert.IsNotNull(isaCopy); Assert.AreEqual("ISA", isaCopy.SegmentId); Assert.AreEqual("Author Info Qualifier", isaCopy.Elements[0].Name); Assert.AreEqual(2, isaCopy.Elements[0].MinLength); }
/// <summary> /// Adds a <see cref="TypedSegment"/> object to the container /// </summary> /// <typeparam name="T">Segment type</typeparam> /// <param name="segment">Segment to be added to the collection</param> /// <returns>Object reference to segment, if added; otherwise, null</returns> public T AddSegment <T>(T segment) where T : TypedSegment { segment.Initialize(this, this.DelimiterSet); SegmentSpecification spec = this.AllowedChildSegments.FirstOrDefault(acs => acs.SegmentId == segment.Segment.SegmentId); if (spec != null) { this.Segments.Add(segment.Segment); return(segment); } return(null); }
/// <summary> /// This method returns the direction (itinerary) between a starting and ending location /// </summary> /// <param name="startLocation">Starting location</param> /// <param name="endLocation">Ending location</param> /// <param name="segPref">specify the shortest or quickest route</param> /// <returns>a RouteItinerary - just the directions portion of a route</returns> public RouteItinerary GetRouteDirections(Location startLocation, Location endLocation, SegmentPreference segPref) { Route myRoute; try { if (startLocation == null) { throw new System.ArgumentNullException("Start location cannot be null"); } if (endLocation == null) { throw new System.ArgumentNullException("End location cannot be null"); } SegmentSpecification[] routeSegmentsSpec = new SegmentSpecification[2]; routeSegmentsSpec[0] = new SegmentSpecification(); routeSegmentsSpec[0].Waypoint = new Waypoint(); routeSegmentsSpec[0].Waypoint.Name = startLocation.Entity.Name; routeSegmentsSpec[0].Waypoint.Location = startLocation; routeSegmentsSpec[0].Options = new SegmentOptions(); routeSegmentsSpec[0].Options.Preference = segPref; routeSegmentsSpec[1] = new SegmentSpecification(); routeSegmentsSpec[1].Waypoint = new Waypoint(); routeSegmentsSpec[1].Waypoint.Name = endLocation.Entity.Name; routeSegmentsSpec[1].Waypoint.Location = endLocation; routeSegmentsSpec[1].Options = new SegmentOptions(); routeSegmentsSpec[1].Options.Preference = segPref; RouteSpecification routeSpec = new RouteSpecification(); routeSpec.DataSourceName = "MapPoint.NA"; routeSpec.ResultMask = RouteResultMask.Itinerary; routeSpec.Segments = routeSegmentsSpec; myRoute = theMapPointRouteService.CalculateRoute(routeSpec); } catch (ArgumentNullException e) { throw e; // rethrow for app to handle } catch (Exception e) { throw e; // rethrow for app to handle } return(myRoute.Itinerary); }
public T AddSegment <T>(T segment, bool forceAdd) where T : TypedSegment { segment.Initialize(this, _delimiters); SegmentSpecification spec = AllowedChildSegments.FirstOrDefault(acs => acs.SegmentId == segment._segment.SegmentId); if (spec != null || forceAdd) { _segments.Add(segment._segment); return(segment); } else { return(null); } }
/// <summary> /// Adds provided segment to container's collection of segments, forced if indicated /// </summary> /// <param name="segmentString">Segment string to be added</param> /// <param name="forceAdd">Indicates whether the segment should be forced</param> /// <returns>Segment object represented by the provided segment string</returns> public Segment AddSegment(string segmentString, bool forceAdd) { var segment = new Segment(this, this.DelimiterSet, segmentString); SegmentSpecification spec = this.AllowedChildSegments.FirstOrDefault(acs => acs.SegmentId == segment.SegmentId); if (spec != null || segmentString.StartsWith("TA1") || forceAdd) { this.Segments.Add(segment); return(segment); } if (this.SegmentId == "NM1" && new[] { "N3", "N4", "PER", "REF" }.Contains(segment.SegmentId)) { this.Segments.Add(segment); return(segment); } return(null); }
public Segment AddSegment(string segmentString, bool forceAdd) { Segment segment = new Segment(this, _delimiters, segmentString); SegmentSpecification spec = AllowedChildSegments.FirstOrDefault(acs => acs.SegmentId == segment.SegmentId); if (spec != null || segmentString.StartsWith("TA1") || forceAdd) { _segments.Add(segment); return(segment); } else if ((this.SegmentId == "NM1") && (new string[] { "N3", "N4", "PER", "REF" }.Contains(segment.SegmentId))) { _segments.Add(segment); return(segment); } else { return(null); } }
public void CreateIndexedSegmentTable(SegmentSpecification spec, string commonSchema) { var sql = new StringBuilder(); sql.AppendFormat(@" CREATE TABLE [{0}].[{1}]( [InterchangeId] [{2}] NOT NULL, [PositionInInterchange] [int] NOT NULL, [RevisionId] [int] NOT NULL, [TransactionSetId] [{2}] NULL, [ParentLoopId] [{2}] NULL, [LoopId] [{2}] NULL, [Deleted] [bit] NOT NULL, [ErrorId] [{2}] NULL, ", _schema, spec.SegmentId, _identitySqlType); foreach (var element in spec.Elements) { if (element.MaxLength > 0 && element.MaxLength < 4000) { switch (element.Type) { case ElementDataTypeEnum.Decimal: int precision = element.MaxLength > 18 ? 38 : element.MaxLength * 2; int scale = element.MaxLength > 8 ? element.MaxLength / 2 : 4; sql.AppendFormat(" [{0}] [decimal]({1},{2}) NULL,\n", element.Reference, precision, scale); break; case ElementDataTypeEnum.Numeric: if (element.ImpliedDecimalPlaces == 0) { if (element.MaxLength < 5) { sql.AppendFormat(" [{0}] [smallint] NULL,\n", element.Reference); } else if (element.MaxLength <= 10) { sql.AppendFormat(" [{0}] [int] NULL,\n", element.Reference); } else { sql.AppendFormat(" [{0}] [bigint] NULL,\n", element.Reference); } } else { precision = element.MaxLength - element.ImpliedDecimalPlaces + 2; scale = element.ImpliedDecimalPlaces; sql.AppendFormat(" [{0}] [decimal]({1},{2}) NULL,\n", element.Reference, precision, scale); } break; case ElementDataTypeEnum.Date: sql.AppendFormat(" [{0}] [{1}] NULL,\n", element.Reference, _dateType); break; default: sql.AppendFormat(" [{0}] [nvarchar]({1}) NULL,\n", element.Reference, element.MaxLength); break; } } else { sql.AppendFormat(" [{0}] [nvarchar](max) NULL,\n", element.Reference); } } sql.AppendFormat(@" CONSTRAINT [PK_{1}_{0}] PRIMARY KEY CLUSTERED ([InterchangeId] ASC, [PositionInInterchange] ASC, [RevisionId] ASC) ) CREATE NONCLUSTERED INDEX [IX_{1}_{0}] ON [{0}].[{1}] ( [InterchangeId] ASC, [PositionInInterchange] ASC, [RevisionId] ASC, [Deleted] ASC, [ParentLoopId] ASC, [LoopId] ASC ) ", _schema, spec.SegmentId); ExecuteCmd(sql.ToString()); ExecuteCmd(string.Format(@" CREATE VIEW [{0}].[LastRev{1}] AS select * from [{0}].[{1}] a where RevisionId = (select max([RevisionId]) from [{0}].[{1}] b where a.InterchangeId = b.InterchangeId and a.PositionInInterchange = b.PositionInInterchange )", _schema, spec.SegmentId, commonSchema)); }
public void AddSegment( SqlTransaction tran, object interchangeId, int positionInInterchange, int revisionId, object functionalGroupId, object transactionSetId, object parentLoopId, object loopId, bool deleted, DetachedSegment segment, SegmentSpecification spec) { this.SegmentTable.Rows.Add( interchangeId, positionInInterchange, revisionId, functionalGroupId, transactionSetId, parentLoopId, loopId, deleted, segment.SegmentId, segment.SegmentString); if (spec != null) { var parsingError = new StringBuilder(); var fieldNames = new List <string>(); int maxElements = spec.Elements.Count; for (var i = 1; i == 1 || i <= maxElements; i++) { fieldNames.Add($"{i:00}"); } if (!this.ParsedTables.ContainsKey(segment.SegmentId)) { this.ParsedTables.Add(segment.SegmentId, new DataTable()); this.ParsedTables[segment.SegmentId].Columns.Add("InterchangeId", this.identityType); this.ParsedTables[segment.SegmentId].Columns.Add("PositionInInterchange", typeof(int)); this.ParsedTables[segment.SegmentId].Columns.Add("TransactionSetId", this.identityType); this.ParsedTables[segment.SegmentId].Columns.Add("ParentLoopId", this.identityType); this.ParsedTables[segment.SegmentId].Columns.Add("LoopId", this.identityType); this.ParsedTables[segment.SegmentId].Columns.Add("RevisionId", typeof(int)); this.ParsedTables[segment.SegmentId].Columns.Add("Deleted", typeof(bool)); foreach (string f in fieldNames) { this.ParsedTables[segment.SegmentId].Columns.Add(f, typeof(string)); } this.ParsedTables[segment.SegmentId].Columns.Add("ErrorId", this.identityType); } DataRow row = this.ParsedTables[segment.SegmentId].NewRow(); row["InterchangeId"] = interchangeId; row["PositionInInterchange"] = positionInInterchange; row["TransactionSetId"] = transactionSetId ?? DBNull.Value; row["ParentLoopId"] = parentLoopId ?? DBNull.Value; row["LoopId"] = loopId ?? DBNull.Value; row["RevisionId"] = revisionId; row["Deleted"] = deleted; for (var i = 1; i <= segment.ElementCount && i <= maxElements; i++) { try { string val = segment.GetElement(i); var elementSpec = spec.Elements[i - 1]; int maxLength = elementSpec.MaxLength; var column = $"{i:00}"; if (maxLength > 0 && val.Length > maxLength) { var message = string.Format( Resources.ElementTruncatedWarning, interchangeId, positionInInterchange, segment.SegmentId, i, maxLength); Trace.TraceInformation(message); parsingError.AppendLine(message); val = val.Substring(0, maxLength); } if (elementSpec.Type == ElementDataType.Numeric && elementSpec.ImpliedDecimalPlaces > 0) { int intVal; if (string.IsNullOrWhiteSpace(val)) { row[column] = null; } else if (int.TryParse(val, out intVal)) { var denominator = (decimal)Math.Pow(10, elementSpec.ImpliedDecimalPlaces); row[column] = intVal / denominator; } else { var message = string.Format( "Element {2}{3:00} in position {1} of interchange {0} cannot be indexed because '{4}' could not be parsed into an implied decimal with precision {5}.", interchangeId, positionInInterchange, segment.SegmentId, i, val, elementSpec.ImpliedDecimalPlaces); Trace.TraceInformation(message); parsingError.AppendLine(message); row[column] = null; } } else if (elementSpec.Type == ElementDataType.Numeric || elementSpec.Type == ElementDataType.Decimal) { decimal decVal; if (string.IsNullOrWhiteSpace(val)) { row[column] = null; } else if (decimal.TryParse(val, out decVal)) { row[column] = decVal; } else { var message = string.Format( "Element {2}{3:00} in position {1} of interchange {0} cannot be indexed because '{4}' could not be parsed into a decimal.", interchangeId, positionInInterchange, segment.SegmentId, i, val); Trace.TraceInformation(message); parsingError.AppendLine(message); row[column] = null; } } else if (elementSpec.Type == ElementDataType.Date) { if (string.IsNullOrWhiteSpace(val)) { row[column] = null; } else { DateTime date; if (val.Length == 8 && DateTime.TryParse( $"{val.Substring(0, 4)}-{val.Substring(4, 2)}-{val.Substring(6, 2)}", out date)) { row[column] = date; } else { var message = string.Format( "Element {2}{3:00} in position {1} of interchange {0} cannot be indexed because '{4}' could not be parsed into a date.", interchangeId, positionInInterchange, segment.SegmentId, i, val); Trace.TraceInformation(message); parsingError.AppendLine(message); row[column] = null; } } } else { row[column] = val; } } catch (Exception e) { var message = string.Format( "Error parsing '{0}' using spec {1} with {2} elements: {3}", segment.SegmentString, spec.SegmentId, spec.Elements.Count(), e.Message); Trace.TraceInformation(message); parsingError.AppendLine(message); } } if (parsingError.Length > 0) { row["ErrorId"] = this.errorRepo.PersistParsingError( interchangeId, positionInInterchange, revisionId, parsingError.ToString()); } this.ParsedTables[segment.SegmentId].Rows.Add(row); } }
public void SerializeSegmentSet() { SegmentSet set = new SegmentSet { Name = "4010" }; SegmentSpecification isa = new SegmentSpecification { SegmentId = "ISA" }; set.Segments.Add(isa); isa.Elements.Add(new ElementSpecification { Name = "Author Info Qualifier", Required = true, MinLength = 2, MaxLength = 2, Type = ElementDataTypeEnum.Identifier }); string xml = set.Serialize(); Trace.Write(xml); SegmentSet copy = SegmentSet.Deserialize(xml); SegmentSpecification isaCopy = copy.Segments.FirstOrDefault(s => s.SegmentId == "ISA"); Assert.IsNotNull(isaCopy); Assert.AreEqual("ISA", isaCopy.SegmentId); Assert.AreEqual("Author Info Qualifier", isaCopy.Elements[0].Name); Assert.AreEqual(2, isaCopy.Elements[0].MinLength); }