private string ResolveProperties(string aliasName, string propertyName) { IDictionary <string, string[]> fieldResults = context.GetPropertyResultsMapByAlias(aliasName); ISqlLoadable persister = context.GetEntityPersisterByAlias(aliasName); string suffix = context.GetEntitySuffixByAlias(aliasName); if ("*".Equals(propertyName)) { if (fieldResults.Count != 0) { throw new QueryException("Using return-propertys together with * syntax is not supported."); } aliasesFound++; return(persister.SelectFragment(aliasName, suffix)); } else { string[] columnAliases; // Let return-propertys override whatever the persister has for aliases. if (!fieldResults.TryGetValue(propertyName, out columnAliases)) { columnAliases = persister.GetSubclassPropertyColumnAliases(propertyName, suffix); } if (columnAliases == null || columnAliases.Length == 0) { throw new QueryException("No column name found for property [" + propertyName + "] for alias [" + aliasName + "]", originalQueryString); } if (columnAliases.Length != 1) { // TODO: better error message since we actually support composites if names are explicitly listed. throw new QueryException( "SQL queries only support properties mapped to a single column - property [" + propertyName + "] is mapped to " + columnAliases.Length + " columns.", originalQueryString); } aliasesFound++; return(columnAliases[0]); } }
private string ResolveProperties( string aliasName, string propertyName, IDictionary fieldResults, ISqlLoadable currentPersister, string suffix) { /*int currentPersisterIndex = getPersisterIndex( aliasName ); if ( !aliasName.Equals( aliases[currentPersisterIndex] ) ) { throw new QueryException( "Alias [" + aliasName + "] does not correspond to return alias " + aliases[currentPersisterIndex], sqlQuery ); }*/ if ("*".Equals(propertyName)) { if (fieldResults.Count > 0) { throw new QueryException("Using return-propertys together with * syntax is not supported."); } aliasesFound++; return currentPersister.SelectFragment(aliasName, suffix); } else { string[] columnAliases; // Let return-propertys override whatever the persister has for aliases. columnAliases = (string[]) fieldResults[propertyName]; if (columnAliases == null) { columnAliases = currentPersister.GetSubclassPropertyColumnAliases(propertyName, suffix); } if (columnAliases == null || columnAliases.Length == 0) { throw new QueryException("No column name found for property [" + propertyName + "] for alias [" + aliasName + "]", sqlQuery); } if (columnAliases.Length != 1) { // TODO: better error message since we actually support composites if names are explicitly listed. throw new QueryException("SQL queries only support properties mapped to a single column - property [" + propertyName + "] is mapped to " + columnAliases.Length + " columns.", sqlQuery); } aliasesFound++; return columnAliases[0]; } }
/// <summary> /// Inspired by the parsing done in TJDO /// TODO: Should record how many properties we have referred to - and throw exception if we don't get them all aka AbstractQueryImpl /// </summary> /// <returns></returns> public string SubstituteBrackets() { string sqlString = sqlQuery; StringBuilder result = new StringBuilder(); int left, right; // replace {....} with corresponding column aliases for (int curr = 0; curr < sqlString.Length; curr = right + 1) { if ((left = sqlString.IndexOf('{', curr)) < 0) { result.Append(sqlString.Substring(curr)); break; } result.Append(sqlString.Substring(curr, left - curr)); if ((right = sqlString.IndexOf('}', left + 1)) < 0) { throw new QueryException("Unmatched braces for alias path", sqlString); } string aliasPath = sqlString.Substring(left + 1, right - left - 1); int firstDot = aliasPath.IndexOf('.'); string aliasName = firstDot == -1 ? aliasPath : aliasPath.Substring(0, firstDot); ISqlLoadable currentPersister = GetPersisterByResultAlias(aliasName); if (currentPersister == null) { // TODO: Do we throw this or pass through as per Hibernate to allow for escape sequences as per HB-898 throw new QueryException(string.Format("Alias [{0}] does not correspond to any of the supplied return aliases = {1}", aliasName, aliases), sqlQuery); //result.Append( "{" + aliasPath + "}" ); //continue; } int currentPersisterIndex = GetPersisterIndex(aliasName); if (firstDot == -1) { // TODO: should this one also be aliased/quoted instead of just directly inserted ? result.Append(aliasPath); } else { if (aliasName != aliases[currentPersisterIndex]) { throw new QueryException(string.Format("Alias [{0}] does not correspond to return alias {1}", aliasName, aliases[currentPersisterIndex]), sqlQuery); } string propertyName = aliasPath.Substring(firstDot + 1); if ("*".Equals(propertyName)) { result.Append(currentPersister.SelectFragment(aliasName, Suffixes[currentPersisterIndex])); } else { // Here it would be nice just to be able to do result.Append( getAliasFor( currentPersister, propertyName )) // but that requires more exposure of the internal maps of the persister... // but it should be possible as propertyname should be unique for all persisters string[] columnAliases; /* * if ( AbstractEntityPersister.ENTITY_CLASS.Equals( propertyName ) * { * columnAliases = new string[1]; * columnAliases[0] = currentPersister.GetDiscriminatorAlias( suffixes[ currentPersisterIndex ] ) ; * } * else */ columnAliases = currentPersister.GetSubclassPropertyColumnAliases(propertyName, Suffixes[currentPersisterIndex]); if (columnAliases == null || columnAliases.Length == 0) { throw new QueryException(string.Format("No column name found for property [{0}]", propertyName), sqlQuery); } if (columnAliases.Length != 1) { throw new QueryException(string.Format("SQL queries only support properties mapped to a single column. Property [{0}] is mapped to {1} columns.", propertyName, columnAliases.Length), sqlQuery); } result.Append(columnAliases[0]); } } } // Possibly handle :something parameters for the query? return(result.ToString()); }