/// <summary> /// For references to versionable types that should float, mark them for floating /// </summary> private void FloatVersionableRefs(XmlDocument result) { var refs = new List<Tuple<ItemType, string>>(); const string _needs_float = "_needs_float"; result.VisitDescendantsAndSelf(e => { switch (e.LocalName) { case "id": case "config_id": case "source_id": case "related_id": return; } var type = e.Attribute("type"); ItemType itemType; // Find all of the elements referencing versionable item types if (!e.HasAttribute(XmlFlags.Attr_Float) && !string.IsNullOrEmpty(type) && _itemTypesByName.TryGetValue(type.ToLowerInvariant(), out itemType) && itemType.IsVersionable) { ItemType parent; switch (e.LocalName) { case "Item": // For item tags that are float properties, or root level item tags, set them to float if (e.Parent().Parent() != null && e.Parent().Parent().LocalName == "Item" && e.Attribute("action", "") != "get") { if (_itemTypesByName.TryGetValue(e.Parent().Parent().Attribute("type").ToLowerInvariant(), out parent) && parent.FloatProperties.Contains(e.Parent().LocalName)) { e.SetAttribute(XmlFlags.Attr_Float, "1"); e.SetAttribute("id", e.Element("config_id", e.Attribute("id"))); } } else { e.SetAttribute(XmlFlags.Attr_Float, "1"); e.SetAttribute("id", e.Element("config_id", e.Attribute("id"))); } break; default: // For item properties (with no Item tag) set to float, make sure they float if (!e.Elements().Any() && e.Parent().LocalName == "Item" && _itemTypesByName.TryGetValue(e.Parent().Attribute("type").ToLowerInvariant(), out parent) && parent.FloatProperties.Contains(e.LocalName)) { refs.Add(Tuple.Create(itemType, e.InnerText)); e.SetAttribute(_needs_float, "1"); } break; } } }); var queries = (from r in refs group r by r.Item1 into g select "<Item type=\"" + g.Key.Name + "\" action=\"get\" select=\"config_id\" idlist=\"" + g.Select(i => i.Item2).Distinct().Aggregate((p, c) => p + "," + c) + "\" />"); var resultItems = queries.SelectMany(q => _conn.GetItems("ApplyItem", q)) .ToDictionary(e => ItemReference.FromFullItem(e, false), e => e.Element("config_id", "")); result.VisitDescendantsAndSelf(e => { string configId; if (e.HasAttribute(_needs_float) && resultItems.TryGetValue(ItemReference.FromItemProp(e), out configId)) { e.RemoveAttribute(_needs_float); e.SetAttribute(XmlFlags.Attr_Float, "1"); e.InnerText = configId; } }); }
/// <summary> /// Convert properties marked as float to a search using a where clause for more convenient execution /// </summary> private void ConvertFloatProps(XmlDocument doc) { doc.VisitDescendantsAndSelf(e => { if (e.HasAttribute(XmlFlags.Attr_Float)) { e.RemoveAttribute(XmlFlags.Attr_Float); if (!string.IsNullOrEmpty(e.Attribute("id")) && !string.IsNullOrEmpty(e.Attribute("type"))) { e.SetAttribute(XmlFlags.Attr_ConfigId, e.Attribute("id")); e.SetAttribute("where", string.Format("[{0}].[config_id] = '{1}'", e.Attribute("type").Replace(' ', '_'), e.Attribute("id"))); e.RemoveAttribute("id"); } else if (!e.Elements().Any()) { var configId = e.InnerText; e.InnerText = ""; e.Elem("Item") .Attr("type", e.Attribute("type")) .Attr("action", "get") .Attr(XmlFlags.Attr_ConfigId, configId) .Attr("where", string.Format("[{0}].[config_id] = '{1}'", e.Attribute("type").Replace(' ', '_'), configId)); } } }); }