private static List <string> GetResultColumns(HbmReturnDiscriminator discriminatorSchema) { string column = Unquote(discriminatorSchema.column); List <string> allResultColumns = new List <string>(); if (column != null) { allResultColumns.Add(column); } return(allResultColumns); }
private IDictionary <string, string[]> BindPropertyResults(string alias, HbmReturnDiscriminator discriminatorSchema, HbmReturnProperty[] returnProperties, PersistentClass pc) { Dictionary <string, string[]> propertyresults = new Dictionary <string, string[]>(); // maybe a concrete SQLpropertyresult type, but Map is exactly what is required at the moment if (discriminatorSchema != null) { propertyresults["class"] = GetResultColumns(discriminatorSchema).ToArray(); } List <HbmReturnProperty> properties = new List <HbmReturnProperty>(); List <string> propertyNames = new List <string>(); foreach (HbmReturnProperty returnPropertySchema in returnProperties ?? new HbmReturnProperty[0]) { string name = returnPropertySchema.name; if (pc == null || name.IndexOf('.') == -1) { //if dotted and not load-collection nor return-join //regular property properties.Add(returnPropertySchema); propertyNames.Add(name); } else { // Reorder properties // 1. get the parent property // 2. list all the properties following the expected one in the parent property // 3. calculate the lowest index and insert the property int dotIndex = name.LastIndexOf('.'); string reducedName = name.Substring(0, dotIndex); IValue value = pc.GetRecursiveProperty(reducedName).Value; IEnumerable <Mapping.Property> parentPropIter; if (value is Component) { Component comp = (Component)value; parentPropIter = comp.PropertyIterator; } else if (value is ToOne) { ToOne toOne = (ToOne)value; PersistentClass referencedPc = mappings.GetClass(toOne.ReferencedEntityName); if (toOne.ReferencedPropertyName != null) { try { parentPropIter = ((Component)referencedPc.GetRecursiveProperty(toOne.ReferencedPropertyName).Value).PropertyIterator; } catch (InvalidCastException e) { throw new MappingException("dotted notation reference neither a component nor a many/one to one", e); } } else { try { parentPropIter = ((Component)referencedPc.IdentifierProperty.Value).PropertyIterator; } catch (InvalidCastException e) { throw new MappingException("dotted notation reference neither a component nor a many/one to one", e); } } } else { throw new MappingException("dotted notation reference neither a component nor a many/one to one"); } bool hasFollowers = false; List <string> followers = new List <string>(); foreach (Mapping.Property prop in parentPropIter) { string currentPropertyName = prop.Name; string currentName = reducedName + '.' + currentPropertyName; if (hasFollowers) { followers.Add(currentName); } if (name.Equals(currentName)) { hasFollowers = true; } } int index = propertyNames.Count; int followersSize = followers.Count; for (int loop = 0; loop < followersSize; loop++) { string follower = followers[loop]; int currentIndex = GetIndexOfFirstMatchingProperty(propertyNames, follower); index = currentIndex != -1 && currentIndex < index ? currentIndex : index; } propertyNames.Insert(index, name); properties.Insert(index, returnPropertySchema); } } ISet <string> uniqueReturnProperty = new HashedSet <string>(); foreach (HbmReturnProperty returnPropertySchema in properties) { string name = returnPropertySchema.name; if ("class".Equals(name)) { throw new MappingException( "class is not a valid property name to use in a <return-property>, use <return-discriminator> instead" ); } //TODO: validate existing of property with the chosen name. (secondpass ) List <string> allResultColumns = GetResultColumns(returnPropertySchema); if (allResultColumns.Count == 0) { throw new MappingException( "return-property for alias " + alias + " must specify at least one column or return-column name" ); } if (uniqueReturnProperty.Contains(name)) { throw new MappingException( "duplicate return-property for property " + name + " on alias " + alias ); } uniqueReturnProperty.Add(name); // the issue here is that for <return-join/> representing an entity collection, // the collection element values (the property values of the associated entity) // are represented as 'element.{propertyname}'. Thus the StringHelper.root() // here puts everything under 'element' (which additionally has significant // meaning). Probably what we need to do is to something like this instead: // String root = StringHelper.root( name ); // String key = root; // by default // if ( !root.equals( name ) ) { // // we had a dot // if ( !root.equals( alias ) { // // the root does not apply to the specific alias // if ( "elements".equals( root ) { // // we specifically have a <return-join/> representing an entity collection // // and this <return-property/> is one of that entity's properties // key = name; // } // } // } // but I am not clear enough on the intended purpose of this code block, especially // in relation to the "Reorder properties" code block above... // String key = StringHelper.root( name ); string key = name; string[] intermediateResults; if (!propertyresults.TryGetValue(key, out intermediateResults)) { propertyresults[key] = allResultColumns.ToArray(); } else { ArrayHelper.AddAll(intermediateResults, allResultColumns); // TODO: intermediateResults not used after this } } Dictionary <string, string[]> newPropertyResults = new Dictionary <string, string[]>(); foreach (KeyValuePair <string, string[]> entry in propertyresults) { newPropertyResults[entry.Key] = entry.Value; } return(newPropertyResults.Count == 0 ? (IDictionary <string, string[]>) new CollectionHelper.EmptyMapClass <string, string[]>() : newPropertyResults); }