📄 querytranslator.cs
字号:
{
// TODO H3.2 check if the QuerySplitter can do the work (this method is not present in H3.2)
//scan the query string for class names appearing in the from clause and replace
//with all persistent implementors of the class/interface, returning multiple
//query strings (make sure we don't pick up a class in the select clause!)
//TODO: this is one of the ugliest and most fragile pieces of code in Hibernate...
string[] tokens = StringHelper.Split(ParserHelper.Whitespace + "(),", query, true);
if (tokens.Length == 0)
{
return new String[] {query};
} // just especially for the trivial collection filter
ArrayList placeholders = new ArrayList();
ArrayList replacements = new ArrayList();
StringBuilder templateQuery = new StringBuilder(40);
int count = 0;
string last = null;
int nextIndex = 0;
string next = null;
templateQuery.Append(tokens[0]);
for (int i = 1; i < tokens.Length; i++)
{
//update last non-whitespace token, if necessary
if (!ParserHelper.IsWhitespace(tokens[i - 1]))
{
last = tokens[i - 1].ToLowerInvariant();
}
string token = tokens[i];
if (!ParserHelper.IsWhitespace(token) || last == null)
{
// scan for the next non-whitespace token
if (nextIndex <= i)
{
for (nextIndex = i + 1; nextIndex < tokens.Length; nextIndex++)
{
next = tokens[nextIndex].ToLowerInvariant();
if (!ParserHelper.IsWhitespace(next))
{
break;
}
}
}
//if ( Character.isUpperCase( token.charAt( token.lastIndexOf(".") + 1 ) ) ) {
// added the checks for last!=null and next==null because an ISet can not contain
// a null key in .net - it is valid for a null key to be in a java.util.Set
if (
((last != null && beforeClassTokens.Contains(last)) && (next == null || !notAfterClassTokens.Contains(next))) ||
PathExpressionParser.EntityClass.Equals(last))
{
System.Type clazz = SessionFactoryHelper.GetImportedClass(factory, token);
if (clazz != null)
{
string[] implementors = factory.GetImplementors(clazz.AssemblyQualifiedName);
string placeholder = "$clazz" + count++ + "$";
if (implementors != null)
{
placeholders.Add(placeholder);
replacements.Add(implementors);
}
token = placeholder; //Note this!!
}
}
}
templateQuery.Append(token);
}
string[] results =
StringHelper.Multiply(templateQuery.ToString(), placeholders.GetEnumerator(), replacements.GetEnumerator());
if (results.Length == 0)
{
log.Warn("no persistent classes found for query class: " + query);
}
return results;
}
private static readonly ISet beforeClassTokens = new HashedSet();
private static readonly ISet notAfterClassTokens = new HashedSet();
/// <summary></summary>
static QueryTranslator()
{
beforeClassTokens.Add("from");
//beforeClassTokens.Add("new"); DEFINITELY DON'T HAVE THIS!!
beforeClassTokens.Add(",");
notAfterClassTokens.Add("in");
//notAfterClassTokens.Add(",");
notAfterClassTokens.Add("from");
notAfterClassTokens.Add(")");
}
private static string[][] GenerateColumnNames(IType[] types, ISessionFactoryImplementor f)
{
string[][] names = new string[types.Length][];
for (int i = 0; i < types.Length; i++)
{
int span = types[i].GetColumnSpan(f);
names[i] = new string[span];
for (int j = 0; j < span; j++)
{
names[i][j] = ScalarName(i, j);
}
}
return names;
}
protected override object GetResultColumnOrRow(object[] row, IResultTransformer resultTransformer, IDataReader rs,
ISessionImplementor session)
{
IType[] _returnTypes = ReturnTypes;
row = ToResultRow(row);
bool hasTransform = holderClass != null || resultTransformer != null;
if (hasScalars)
{
string[][] _names = ScalarColumnNames;
int queryCols = _returnTypes.Length;
if (holderClass == null && queryCols == 1)
{
return _returnTypes[0].NullSafeGet(rs, _names[0], session, null);
}
else
{
row = new object[queryCols];
for (int i = 0; i < queryCols; i++)
{
row[i] = _returnTypes[i].NullSafeGet(rs, _names[i], session, null);
}
return row;
}
}
else if (!hasTransform)
{
return (row.Length == 1) ? row[0] : row;
}
else
{
return row;
}
}
protected override IList GetResultList(IList results, IResultTransformer resultTransformer)
{
HolderInstantiator holderInstantiator =
HolderInstantiator.CreateClassicHolderInstantiator(holderConstructor, resultTransformer);
if (holderInstantiator.IsRequired)
{
for (int i = 0; i < results.Count; i++)
{
object[] row = (object[]) results[i];
results[i] = holderInstantiator.Instantiate(row);
}
if (holderConstructor == null && resultTransformer != null)
{
return resultTransformer.TransformList(results);
}
}
return results;
}
private object[] ToResultRow(object[] row)
{
if (selectLength == row.Length)
{
return row;
}
else
{
object[] result = new object[selectLength];
int j = 0;
for (int i = 0; i < row.Length; i++)
{
if (includeInSelect[i])
{
result[j++] = row[i];
}
}
return result;
}
}
internal QueryJoinFragment CreateJoinFragment(bool useThetaStyleInnerJoins)
{
return new QueryJoinFragment(Factory.Dialect, useThetaStyleInnerJoins);
}
internal System.Type HolderClass
{
set { holderClass = value; }
}
protected internal override LockMode[] GetLockModes(IDictionary lockModes)
{
// unfortunately this stuff can't be cached because
// it is per-invocation, not constant for the
// QueryTranslator instance
IDictionary nameLockModes = new Hashtable();
if (lockModes != null)
{
IDictionaryEnumerator it = lockModes.GetEnumerator();
while (it.MoveNext())
{
DictionaryEntry me = it.Entry;
nameLockModes.Add(
GetAliasName((String) me.Key),
me.Value
);
}
}
LockMode[] lockModeArray = new LockMode[names.Length];
for (int i = 0; i < names.Length; i++)
{
LockMode lm = (LockMode) nameLockModes[names[i]];
if (lm == null)
{
lm = LockMode.None;
}
lockModeArray[i] = lm;
}
return lockModeArray;
}
protected override SqlString ApplyLocks(SqlString sql, IDictionary lockModes, Dialect.Dialect dialect)
{
SqlString result;
if (lockModes == null || lockModes.Count == 0)
{
result = sql;
}
else
{
IDictionary aliasedLockModes = new Hashtable();
foreach (DictionaryEntry de in lockModes)
{
aliasedLockModes[GetAliasName((string) de.Key)] = de.Value;
}
IDictionary keyColumnNames = null;
if (dialect.ForUpdateOfColumns)
{
keyColumnNames = new Hashtable();
for (int i = 0; i < names.Length; i++)
{
keyColumnNames[names[i]] = persisters[i].IdentifierColumnNames;
}
}
result = dialect.ApplyLocksToSql(sql, aliasedLockModes, keyColumnNames);
}
LogQuery(queryString, result.ToString());
return result;
}
protected override bool UpgradeLocks()
{
return true;
}
protected override int[] CollectionOwners
{
get { return fetchedCollections.CollectionOwners; }
}
protected bool Compiled
{
get { return compiled; }
}
public override string ToString()
{
return queryString;
}
/// <summary></summary>
protected override int[] Owners
{
get { return owners; }
set { owners = value; }
}
public IDictionary<string, IFilter> EnabledFilters
{
get { return enabledFilters; }
}
public void AddFromJoinOnly(string name, JoinSequence joinSequence)
{
AddJoin(name, joinSequence.GetFromPart());
}
protected internal override bool IsSubselectLoadingEnabled
{
get { return HasSubselectLoadableCollections(); }
}
protected override string[] Aliases
{
get { return names; }
}
protected override EntityType[] OwnerAssociationTypes
{
get { return ownerAssociationTypes; }
}
#region IQueryTranslator Members
public int ExecuteUpdate(QueryParameters queryParameters, ISessionImplementor session)
{
throw new NotSupportedException();
}
public string SQLString
{
get { return sqlString.ToString(); }
}
public IList<string> CollectSqlStrings
{
get
{
IList<string> result = new List<string>(1);
result.Add(sqlString.ToString());
return result;
}
}
public string QueryString
{
get { return queryString; }
}
public string[] ReturnAliases
{
get { return NoReturnAliases; }
}
public string[][] GetColumnNames()
{
return scalarColumnNames;
}
public IParameterTranslations GetParameterTranslations()
{
return new ParameterTranslations(this);
}
public bool ContainsCollectionFetches
{
get { return false; }
}
public bool IsManipulationStatement
{
get
{
// classic parser does not support bulk manipulation statements
return false;
}
}
#endregion
private class ParameterTranslations : IParameterTranslations
{
private readonly QueryTranslator queryTraslator;
public ParameterTranslations(QueryTranslator queryTraslator)
{
this.queryTraslator = queryTraslator;
}
#region IParameterTranslations Members
public bool SupportsOrdinalParameterMetadata
{
get { return false; }
}
public int OrdinalParameterCount
{
get { return 0; }
}
public int GetOrdinalParameterSqlLocation(int ordinalPosition)
{
return 0;
}
public IType GetOrdinalParameterExpectedType(int ordinalPosition)
{
return null;
}
public IEnumerable<string> GetNamedParameterNames()
{
return queryTraslator.namedParameters.Keys;
}
public int[] GetNamedParameterSqlLocations(string name)
{
return queryTraslator.GetNamedParameterLocs(name);
}
public IType GetNamedParameterExpectedType(string name)
{
return null;
}
#endregion
}
public override string QueryIdentifier
{
get { return queryIdentifier; }
}
internal void AddQuerySpaces(string[] spaces)
{
for (int i = 0; i < spaces.Length; i++)
{
querySpaces.Add(spaces[i]);
}
if (superQuery != null)
superQuery.AddQuerySpaces(spaces);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -