void Application_Start(object sender, EventArgs e) { _containerProvider = new ContainerProvider(ContainerCreationExtentions.CreateNew().LoadDefaultPackage("KindergartenApp")); SessionFactoryHelper.CreateSessionFactoryWithDBUpdate(); using (var session = SessionFactoryHelper.SessionFactory.OpenSession()) { var exist = session.Query <Sensitivity>().Any(); if (!exist) { var s1 = new Sensitivity { Description = "לקטוז" }; var s2 = new Sensitivity { Description = "גלוטן" }; var s3 = new Sensitivity { Description = "בוטנים" }; var s4 = new Sensitivity { Description = "אגוזים" }; var s5 = new Sensitivity { Description = "ביצים" }; session.Save(s1); session.Save(s2); session.Save(s3); session.Save(s4); session.Save(s5); } } }
private void ProcessMetaTypeDiscriminatorIfNecessary(IASTNode lhs, IASTNode rhs) { // this method inserts the discriminator value for the rhs node so that .class queries on <any> mappings work with the class name var lhsNode = lhs as SqlNode; var rhsNode = rhs as SqlNode; if (lhsNode == null || rhsNode == null) { return; } if (rhsNode.Text == null) { var lhsNodeMetaType = lhsNode.DataType as MetaType; if (lhsNodeMetaType != null) { string className = SessionFactoryHelper.GetImportedClassName(rhsNode.OriginalText); object discriminatorValue = lhsNodeMetaType.GetMetaValue(TypeNameParser.Parse(className).Type); rhsNode.Text = discriminatorValue.ToString(); return; } } if (lhsNode.Text == null) { var rhsNodeMetaType = rhsNode.DataType as MetaType; if (rhsNodeMetaType != null) { string className = SessionFactoryHelper.GetImportedClassName(lhsNode.OriginalText); object discriminatorValue = rhsNodeMetaType.GetMetaValue(TypeNameParser.Parse(className).Type); lhsNode.Text = discriminatorValue.ToString(); return; } } }
private static void SaveAndLoadEmployeeWithNH() { var employeeId = 0; var sessionFactory = SessionFactoryHelper.GetSessionFactory(ConfigurationManager.ConnectionStrings["cnn"].ConnectionString); using (var session = sessionFactory.OpenSession()) { using (var tran = session.BeginTransaction()) { var employeeTypes = session.QueryOver <EmployeeType>().List <EmployeeType>(); var employee = new Employee(); employee.ChangeAdress("Funchal"); employee.ChangeName("Luis"); employee.SetEmployeeType(employeeTypes.First()); employee.AddContact(new Contact("123123123", ContactKind.Phone)); employee.AddContact(new Contact("123123123", ContactKind.Phone)); session.SaveOrUpdate(employee); tran.Commit(); employeeId = employee.EmployeeId; } } using (var session = sessionFactory.OpenSession()) { using (var tran = session.BeginTransaction()) { var employee = session.Load <Employee>(employeeId); Console.WriteLine(employee); } } }
private ConstructorInfo ResolveConstructor(String path) { string importedClassName = SessionFactoryHelper.GetImportedClassName(path); string className = StringHelper.IsEmpty(importedClassName) ? path : importedClassName; if (className == null) { throw new SemanticException("Unable to locate class [" + path + "]"); } try { System.Type holderClass = ReflectHelper.ClassForName(className); return(ReflectHelper.GetConstructor(holderClass, _constructorArgumentTypes)); } catch (TypeLoadException e) { throw new QueryException("Unable to locate class [" + className + "]", e); } catch (InstantiationException e) { // this is the exception returned by ReflectHelper.getConstructor() if it cannot // locate an appropriate constructor throw new QueryException("Unable to locate appropriate constructor on class [" + className + "]", e); } }
private IQueryable ResolveEntityJoinReferencedPersister(FromReferenceNode path) { string entityName = path.Path; var persister = SessionFactoryHelper.FindQueryableUsingImports(entityName); if (persister == null && entityName != null) { var implementors = SessionFactoryHelper.Factory.GetImplementors(entityName); //Possible case - join on interface if (implementors.Length == 1) { persister = (IQueryable)SessionFactoryHelper.Factory.TryGetEntityPersister(implementors[0]); } } if (persister != null) { return(persister); } if (path.Type == IDENT) { throw new QuerySyntaxException(entityName + " is not mapped"); } //Keep old exception for DOT node throw new InvalidPathException("Invalid join: " + entityName); }
private void InitializeColumnNames() { // Generate an 2d array of column names, the first dimension is parallel with the // return types array. The second dimension is the list of column names for each // type. // todo: we should really just collect these from the various SelectExpressions, rather than regenerating here _columnNames = SessionFactoryHelper.GenerateColumnNames(_queryReturnTypes); }
public static bool IsTransient(ISession session, object obj) { ISessionFactoryImplementor sessionFactoryImpl = session.SessionFactory as ISessionFactoryImplementor; // Here `obj` may be an instance of an NHibernate proxy, so we cannot simply use // `obj.GetType().FullName`, we need to get the real underlying type. var persister = new SessionFactoryHelper(sessionFactoryImpl) .RequireClassPersister(NHibernateUtil.GetClass(obj).FullName); bool?yes = persister.IsTransient(obj, (ISessionImplementor)session); return(yes ?? default(bool)); }
private IQueryable ObtainQueryable(ICriteriaQuery criteriaQuery) { IQueryable queryable = criteriaQuery.Factory.GetEntityPersister(_entityClass.FullName) as IQueryable; if (queryable == null) { queryable = SessionFactoryHelper.FindQueryableUsingImports( criteriaQuery.Factory, _entityClass.FullName); } return(queryable); }
IASTNode CreateIntoClause(string path, IASTNode propertySpec) { var persister = (IQueryable)SessionFactoryHelper.RequireClassPersister(path); var intoClause = (IntoClause)adaptor.Create(INTO, "into"); intoClause.SetFirstChild(propertySpec); intoClause.Initialize(persister); AddQuerySpaces(persister.QuerySpaces); return(intoClause); }
public bool?IsPersisted(object obj, ISession session) { try { var sessionFactoryImpl = (ISessionFactoryImplementor)session.SessionFactory; var persister = new SessionFactoryHelper(sessionFactoryImpl).RequireClassPersister(obj.GetType().FullName); return(!persister.IsTransient(obj, (ISessionImplementor)session)); } catch (Exception) { return(null); } }
private void DialectFunction(IASTNode exprList) { _function = SessionFactoryHelper.FindSQLFunction(_methodName); if (_function != null) { DataType = SessionFactoryHelper.FindFunctionReturnType(_methodName, (IEnumerable <IASTNode>)exprList); } //TODO: /*else { * methodName = (String) getWalker().getTokenReplacements().get( methodName ); * }*/ }
private IQueryable ResolveEntityJoinReferencedPersister(IASTNode path) { if (path.Type == IDENT) { var pathIdentNode = (IdentNode)path; return(SessionFactoryHelper.FindQueryableUsingImports(pathIdentNode.Path)); } else if (path.Type == DOT) { var pathText = ASTUtil.GetPathText(path); return(SessionFactoryHelper.FindQueryableUsingImports(pathText)); } return(null); }
public CriteriaQueryTranslator(ISessionFactoryImplementor factory, CriteriaImpl criteria, string rootEntityName, string rootSQLAlias) { rootCriteria = criteria; this.rootEntityName = rootEntityName; sessionFactory = factory; this.rootSQLAlias = rootSQLAlias; helper = new SessionFactoryHelper(factory); CreateAliasCriteriaMap(); CreateAssociationPathCriteriaMap(); CreateCriteriaEntityNameMap(); CreateCriteriaCollectionPersisters(); CreateCriteriaSQLAliasMap(); }
private IQueryable ResolveEntityJoinReferencedPersister(IASTNode path) { if (path.Type == IDENT) { var pathIdentNode = (IdentNode)path; // Since IDENT node is not expected for implicit join path, we can throw on not found persister return((IQueryable)SessionFactoryHelper.RequireClassPersister(pathIdentNode.Path)); } else if (path.Type == DOT) { var pathText = ASTUtil.GetPathText(path); return(SessionFactoryHelper.FindQueryableUsingImports(pathText)); } return(null); }
private void InitializeColumnNames() { // Generate an 2d array of column names, the first dimension is parallel with the // return types array. The second dimension is the list of column names for each // type. // todo: we should really just collect these from the various SelectExpressions, rather than regenerating here _columnNames = SessionFactoryHelper.GenerateColumnNames(_queryReturnTypes); _columnNamesStartPositions = new int[_columnNames.Length]; int startPosition = 1; for (int i = 0; i < _columnNames.Length; i++) { _columnNamesStartPositions[i] = startPosition; startPosition += _columnNames[i].Length; } }
public ChatWindow() { Ice.InitializationData initData = new Ice.InitializationData(); initData.properties = Ice.Util.createProperties(); initData.properties.load("config.client"); // Dispatch servant calls and AMI callbacks with this windows Dispatcher. initData.dispatcher = (System.Action action, Ice.Connection connection) => { Dispatcher.BeginInvoke(DispatcherPriority.Normal, action); }; _factory = new SessionFactoryHelper(initData, this); InitializeComponent(); Util.locateOnScreen(this); }
public ChatWindow() { Ice.InitializationData initData = new Ice.InitializationData(); initData.properties = Ice.Util.createProperties(); initData.properties.load("config.client"); // Dispatch servant calls and AMI callbacks with this windows Dispatcher. initData.dispatcher = (System.Action action, Ice.Connection connection) => { Dispatcher.BeginInvoke(DispatcherPriority.Normal, action); }; _factory = new SessionFactoryHelper(initData, this); InitializeComponent(); Util.locateOnScreen(this); }
public void CreateFactoryTest() { var factory = new SessionFactoryHelper(); factory.CreateSessionFactory(true); using (var session = factory.CreateSessionFactory().OpenSession()) { session.Save(new CommunicationType() { Value = "Email" }); session.Save(new CommunicationType() { Value = "Phone" }); } }
public CriteriaQueryTranslator(ISessionFactoryImplementor factory, CriteriaImpl criteria, string rootEntityName, string rootSQLAlias) { rootCriteria = criteria; this.rootEntityName = rootEntityName; sessionFactory = factory; this.rootSQLAlias = rootSQLAlias; helper = new SessionFactoryHelper(factory); collectedParameterSpecifications = new List <IParameterSpecification>(); namedParameters = new List <NamedParameter>(); CreateAliasCriteriaMap(); CreateAssociationPathCriteriaMap(); CreateCriteriaEntityNameMap(); CreateCriteriaCollectionPersisters(); CreateCriteriaSQLAliasMap(); CreateSubQuerySpaces(); }
public override void ResolveIndex(IASTNode parent) { // An ident node can represent an index expression if the ident // represents a naked property ref // *Note: this makes the assumption (which is currently the case // in the hql-sql grammar) that the ident is first resolved // itself (addrExpr -> resolve()). The other option, if that // changes, is to call resolve from here; but it is // currently un-needed overhead. if (!(IsResolved && _nakedPropertyRef)) { throw new InvalidOperationException(); } string propertyName = OriginalText; if (!DataType.IsCollectionType) { throw new SemanticException("Collection expected; [" + propertyName + "] does not refer to a collection property"); } // TODO : most of below was taken verbatim from DotNode; should either delegate this logic or super-type it CollectionType type = (CollectionType)DataType; string role = type.Role; IQueryableCollection queryableCollection = SessionFactoryHelper.RequireQueryableCollection(role); string columnTableAlias = FromElement.TableAlias; FromElementFactory factory = new FromElementFactory( Walker.CurrentFromClause, FromElement, propertyName, null, FromElement.ToColumns(columnTableAlias, propertyName, false), true ); FromElement elem = factory.CreateCollection(queryableCollection, role, JoinType.InnerJoin, false, true); FromElement = elem; Walker.AddQuerySpaces(queryableCollection.CollectionSpaces); // Always add the collection's query spaces. }
private void DialectFunction(IASTNode exprList) { _function = SessionFactoryHelper.FindSQLFunction(_methodName); if (_function != null) { IASTNode child = null; if (exprList != null) { child = _methodName == "iif" ? exprList.GetChild(1) : exprList.GetChild(0); } DataType = SessionFactoryHelper.FindFunctionReturnType(_methodName, child); } //TODO: /*else { * methodName = (String) getWalker().getTokenReplacements().get( methodName ); * }*/ }
/// <summary> /// Is the given property name a reference to the primary key of the associated /// entity construed by the given entity type? /// For example, consider a fragment like order.customer.id /// (where order is a from-element alias). Here, we'd have: /// propertyName = "id" AND /// owningType = ManyToOneType(Customer) /// and are being asked to determine whether "customer.id" is a reference /// to customer's PK... /// </summary> /// <param name="propertyName">The name of the property to check.</param> /// <param name="owningType">The type represeting the entity "owning" the property</param> /// <returns>True if propertyName references the entity's (owningType->associatedEntity) primary key; false otherwise.</returns> private bool IsReferenceToPrimaryKey(string propertyName, EntityType owningType) { IEntityPersister persister = SessionFactoryHelper.Factory.GetEntityPersister(owningType.GetAssociatedEntityName()); if (persister.EntityMetamodel.HasNonIdentifierPropertyNamedId) { // only the identifier property field name can be a reference to the associated entity's PK... return(propertyName == persister.IdentifierPropertyName && owningType.IsReferenceToPrimaryKey); } // here, we have two possibilities: // 1) the property-name matches the explicitly identifier property name // 2) the property-name matches the implicit 'id' property name if (EntityPersister.EntityID == propertyName) { // the referenced node text is the special 'id' return(owningType.IsReferenceToPrimaryKey); } string keyPropertyName = SessionFactoryHelper.GetIdentifierOrUniqueKeyPropertyName(owningType); return(keyPropertyName != null && keyPropertyName == propertyName && owningType.IsReferenceToPrimaryKey); }
public CriteriaQueryTranslator(ISessionFactoryImplementor factory, CriteriaImpl criteria, string rootEntityName, string rootSQLAlias) { rootCriteria = criteria; sessionFactory = factory; rootPersister = GetQueryablePersister(rootEntityName); this.rootSQLAlias = rootSQLAlias; helper = new SessionFactoryHelper(factory); collectedParameterSpecifications = new List <IParameterSpecification>(); namedParameters = new List <NamedParameter>(); CreateAliasCriteriaMap(); CreateAssociationPathCriteriaMap(); CreateEntityJoinMap(); CreateCriteriaEntityNameMap(); CreateCriteriaCollectionPersisters(); CreateCriteriaSQLAliasMap(); CreateSubQuerySpaces(); supportsQueryCache = GetPersisters().All(o => o.SupportsQueryCache); }
private void DereferenceEntityJoin(string classAlias, EntityType propertyType, bool impliedJoin, IASTNode parent) { _dereferenceType = DerefEntity; if (Log.IsDebugEnabled) { Log.Debug("dereferenceEntityJoin() : generating join for " + _propertyName + " in " + FromElement.ClassName + " " + ((classAlias == null) ? "{no alias}" : "(" + classAlias + ")") + " parent = " + ASTUtil.GetDebugstring(parent) ); } // Create a new FROM node for the referenced class. string associatedEntityName = propertyType.GetAssociatedEntityName(); string tableAlias = AliasGenerator.CreateName(associatedEntityName); string[] joinColumns = GetColumns(); string joinPath = Path; if (impliedJoin && Walker.IsInFrom) { _joinType = Walker.ImpliedJoinType; } FromClause currentFromClause = Walker.CurrentFromClause; FromElement elem = currentFromClause.FindJoinByPath(joinPath); /////////////////////////////////////////////////////////////////////////////// // // This is the piece which recognizes the condition where an implicit join path // resolved earlier in a correlated subquery is now being referenced in the // outer query. For 3.0final, we just let this generate a second join (which // is exactly how the old parser handles this). Eventually we need to add this // logic back in and complete the logic in FromClause.promoteJoin; however, // FromClause.promoteJoin has its own difficulties (see the comments in // FromClause.promoteJoin). // // if ( elem == null ) { // // see if this joinPath has been used in a "child" FromClause, and if so // // promote that element to the outer query // FromClause currentNodeOwner = getFromElement().getFromClause(); // FromClause currentJoinOwner = currentNodeOwner.locateChildFromClauseWithJoinByPath( joinPath ); // if ( currentJoinOwner != null && currentNodeOwner != currentJoinOwner ) { // elem = currentJoinOwner.findJoinByPathLocal( joinPath ); // if ( elem != null ) { // currentFromClause.promoteJoin( elem ); // // EARLY EXIT!!! // return; // } // } // } // /////////////////////////////////////////////////////////////////////////////// bool found = elem != null; // even though we might find a pre-existing element by join path, for FromElements originating in a from-clause // we should only ever use the found element if the aliases match (null != null here). Implied joins are // always (?) ok to reuse. bool useFoundFromElement = found && (elem.IsImplied || (AreSame(classAlias, elem.ClassAlias))); if (!useFoundFromElement) { // If this is an implied join in a from element, then use the impled join type which is part of the // tree parser's state (set by the gramamar actions). JoinSequence joinSequence = SessionFactoryHelper .CreateJoinSequence(impliedJoin, propertyType, tableAlias, _joinType, joinColumns); FromElementFactory factory = new FromElementFactory( currentFromClause, GetLhs().FromElement, joinPath, classAlias, joinColumns, impliedJoin ); elem = factory.CreateEntityJoin( associatedEntityName, tableAlias, joinSequence, _fetch, Walker.IsInFrom, propertyType ); } else { currentFromClause.AddDuplicateAlias(classAlias, elem); } SetImpliedJoin(elem); Walker.AddQuerySpaces(elem.EntityPersister.QuerySpaces); FromElement = elem; // This 'dot' expression now refers to the resulting from element. }
private void DereferenceCollection(CollectionType collectionType, bool implicitJoin, bool indexed, string classAlias) { _dereferenceType = DerefCollection; string role = collectionType.Role; //foo.bars.size (also handles deprecated stuff like foo.bars.maxelement for backwardness) IASTNode sibling = NextSibling; bool isSizeProperty = sibling != null && CollectionProperties.IsAnyCollectionProperty(sibling.Text); if (isSizeProperty) { indexed = true; //yuck!} } IQueryableCollection queryableCollection = SessionFactoryHelper.RequireQueryableCollection(role); string propName = Path; FromClause currentFromClause = Walker.CurrentFromClause; if (Walker.StatementType != HqlSqlWalker.SELECT && indexed && classAlias == null) { // should indicate that we are processing an INSERT/UPDATE/DELETE // query with a subquery implied via a collection property // function. Here, we need to use the table name itself as the // qualification alias. // TODO : verify this works for all databases... // TODO : is this also the case in non-"indexed" scenarios? string alias = GetLhs().FromElement.Queryable.TableName; _columns = FromElement.ToColumns(alias, _propertyPath, false, true); } //We do not look for an existing join on the same path, because //it makes sense to join twice on the same collection role FromElementFactory factory = new FromElementFactory( currentFromClause, GetLhs().FromElement, propName, classAlias, GetColumns(), implicitJoin ); FromElement elem = factory.CreateCollection(queryableCollection, role, _joinType, _fetch, indexed); if (Log.IsDebugEnabled) { Log.Debug("dereferenceCollection() : Created new FROM element for " + propName + " : " + elem); } SetImpliedJoin(elem); FromElement = elem; // This 'dot' expression now refers to the resulting from element. if (isSizeProperty) { elem.Text = ""; elem.UseWhereFragment = false; } if (!implicitJoin) { IEntityPersister entityPersister = elem.EntityPersister; if (entityPersister != null) { Walker.AddQuerySpaces(entityPersister.QuerySpaces); } } Walker.AddQuerySpaces(queryableCollection.CollectionSpaces); // Always add the collection's query spaces. }
/// <summary> /// Construct a new SessionFactoryHelperExtensions instance. /// </summary> /// <param name="sfi">The SessionFactory impl to be encapsulated.</param> public SessionFactoryHelperExtensions(ISessionFactoryImplementor sfi) { _sfi = sfi; helper = new SessionFactoryHelper(_sfi); _collectionPropertyMappingByRole = new NullableDictionary <string, IPropertyMapping>(); }
public ScalarCollectionCriteriaInfoProvider(SessionFactoryHelper helper, String role) { this.role = role; this.helper = helper; this.persister = helper.RequireQueryableCollection(role); }
public PolymorphicQuerySourceDetector(ISessionFactoryImplementor sfi) { _sfi = sfi; _sessionFactoryHelper = new SessionFactoryHelper(sfi); }
public void Token(string token, QueryTranslator q) { SessionFactoryHelper helper = new SessionFactoryHelper(q.Factory); string lctoken = token.ToLowerInvariant(); if (first) { first = false; if ("distinct".Equals(lctoken)) { q.Distinct = true; return; } else if ("all".Equals(lctoken)) { q.Distinct = false; return; } } if (afterNew) { afterNew = false; holderClass = helper.GetImportedClass(token); if (holderClass == null) { throw new QueryException("class not found: " + token); } q.HolderClass = holderClass; insideNew = true; } else if (token.Equals(StringHelper.Comma)) { if (readyForAliasOrExpression) { throw new QueryException("alias or expression expected in SELECT"); } q.AppendScalarSelectToken(StringHelper.CommaSpace); readyForAliasOrExpression = true; } else if ("new".Equals(lctoken)) { afterNew = true; readyForAliasOrExpression = false; } else if (StringHelper.OpenParen.Equals(token)) { parenCount++; if (!funcStack.HasFunctions && holderClass != null && !readyForAliasOrExpression) { //opening paren in new Foo ( ... ) readyForAliasOrExpression = true; } else if (funcStack.HasFunctions) { q.AppendScalarSelectToken(token); } else { throw new QueryException("HQL function expected before '(' in SELECT clause."); } readyForAliasOrExpression = true; } else if (StringHelper.ClosedParen.Equals(token)) { parenCount--; if (parenCount < 0) { throw new QueryException("'(' expected before ')' in SELECT clause."); } if (insideNew && !funcStack.HasFunctions && !readyForAliasOrExpression) { //if we are inside a new Result(), but not inside a nested function insideNew = false; } else if (funcStack.HasFunctions) { q.AppendScalarSelectToken(token); IType scalarType = funcStack.GetReturnType(); funcStack.Pop(); // Can't have an alias or expression right after the closing parenthesis of a function call. readyForAliasOrExpression = false; // if all functions were parsed add the type of the first function in stack if (!funcStack.HasFunctions) { q.AddSelectScalar(scalarType); } } } else if (IsHQLFunction(lctoken, q) && token == q.Unalias(token)) { if (!readyForAliasOrExpression && !funcStack.HasFunctions) { // The syntax control inside a functions is delegated to the render throw new QueryException("',' expected before function in SELECT: " + token); } if (funcStack.HasFunctions && funcStack.FunctionGrammar.IsKnownArgument(lctoken)) { // Some function, like extract, may have KnownArgument with the same name of another function q.AppendScalarSelectToken(token); } else { // Is a nested function funcStack.Push(GetFunction(lctoken, q)); q.AppendScalarSelectToken(token); if (!funcStack.SqlFunction.HasArguments && !funcStack.SqlFunction.HasParenthesesIfNoArguments) { q.AddSelectScalar(funcStack.GetReturnType()); funcStack.Pop(); readyForAliasOrExpression = funcStack.HasFunctions; } } } else if (funcStack.HasFunctions) { bool constantToken = false; var expectedParen = parenCount + ((insideNew) ? -1 : 0); if (!readyForAliasOrExpression && expectedParen != funcStack.NestedFunctionCount) { throw new QueryException("'(' expected after HQL function in SELECT"); } try { ParserHelper.Parse(funcStack.PathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q); } catch (QueryException) { if (IsPathExpression(token)) { throw; } // If isn't a path the token is added like part of function arguments constantToken = true; } if (token.StartsWith(ParserHelper.HqlVariablePrefix)) { string name = token.Substring(1); q.AppendScalarSelectParameter(name); } else if (token.Equals(StringHelper.SqlParameter)) { q.AppendScalarSelectParameter(); } else if (constantToken) { q.AppendScalarSelectToken(token); } else { if (funcStack.PathExpressionParser.IsCollectionValued) { q.AddCollection( funcStack.PathExpressionParser.CollectionName, funcStack.PathExpressionParser.CollectionRole); } q.AppendScalarSelectToken(funcStack.PathExpressionParser.WhereColumn); funcStack.PathExpressionParser.AddAssociation(q); } // after a function argument readyForAliasOrExpression = false; } else { if (!readyForAliasOrExpression) { throw new QueryException("',' expected in SELECT before:" + token); } try { //High probablly to find a valid pathExpression ParserHelper.Parse(pathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q); if (pathExpressionParser.IsCollectionValued) { q.AddCollection( pathExpressionParser.CollectionName, pathExpressionParser.CollectionRole); } else if (pathExpressionParser.WhereColumnType.IsEntityType) { q.AddSelectClass(pathExpressionParser.SelectName); } q.AppendScalarSelectTokens(pathExpressionParser.WhereColumns); q.AddSelectScalar(pathExpressionParser.WhereColumnType); pathExpressionParser.AddAssociation(q); } catch (QueryException) { // Accept costants in SELECT: NH-280 // TODO: Parse a costant expression like 5+3+8 (now is not supported in SELECT) if (IsStringCostant(token)) { q.AppendScalarSelectToken(token); q.AddSelectScalar(NHibernateUtil.String); } else if (IsIntegerConstant(token)) { q.AppendScalarSelectToken(token); q.AddSelectScalar(GetIntegerConstantType(token)); } else if (IsFloatingPointConstant(token)) { q.AppendScalarSelectToken(token); q.AddSelectScalar(GetFloatingPointConstantType()); } else if (token.StartsWith(ParserHelper.HqlVariablePrefix)) { string name = token.Substring(1); q.AppendScalarSelectParameter(name); } else if (token.Equals(StringHelper.SqlParameter)) { q.AppendScalarSelectParameter(); } else { throw; } } readyForAliasOrExpression = false; } }
/// <summary> /// Handle Hibernate "implicit" polymorphism, by translating the query string into /// several "concrete" queries against mapped classes. /// </summary> /// <param name="query"></param> /// <param name="factory"></param> /// <returns></returns> /// <exception cref="NHibernate.MappingException"/> public static string[] ConcreteQueries(string query, ISessionFactoryImplementor factory) { //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.... SessionFactoryHelper helper = new SessionFactoryHelper(factory); string[] tokens = StringHelper.Split(StringHelper.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]); bool isSelectClause = StringHelper.EqualsCaseInsensitive("select", 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(); } // select-range is terminated by declaration of "from" isSelectClause = !StringHelper.EqualsCaseInsensitive("from", tokens[i]); string token = tokens[i]; if (!ParserHelper.IsWhitespace(token) || last == null) { //scan for next non-whitespace token if (nextIndex <= i) { for (nextIndex = i + 1; nextIndex < tokens.Length; nextIndex++) { next = tokens[nextIndex].ToLowerInvariant(); if (!ParserHelper.IsWhitespace(next)) { break; } } } // TODO H3.2 Different behavior // NHb: This block is not an exactly port from H3.2 but a port from previous implementation of QueryTranslator if (((last != null && beforeClassTokens.Contains(last)) && (next == null || !notAfterClassTokens.Contains(next))) || PathExpressionParser.EntityClass.Equals(last)) { System.Type clazz = helper.GetImportedClass(token); if (clazz != null) { string[] implementors = factory.GetImplementors(clazz.FullName); 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 void DoToken(string token, QueryTranslator q) { SessionFactoryHelper helper = new SessionFactoryHelper(q.Factory); if (q.IsName(StringHelper.Root(token))) //path expression { DoPathExpression(q.Unalias(token), q); } else if (token.StartsWith(ParserHelper.HqlVariablePrefix)) //named query parameter { var name = token.Substring(1); // this is only a temporary parameter to help with the parsing of hql - // when the type becomes known then this will be converted to its real // parameter type. AppendToken(q, q.GetNamedParameter(name)); } else if (token.Equals(StringHelper.SqlParameter)) { //if the token is a "?" then we have a Parameter so convert it to a SqlCommand.Parameter // instead of appending a "?" to the WhereTokens AppendToken(q, q.GetPositionalParameter()); } else { IQueryable persister = q.GetPersisterUsingImports(token); if (persister != null) // the name of a class { string discrim = persister.DiscriminatorSQLValue; if (InFragment.Null == discrim || InFragment.NotNull == discrim) { throw new QueryException("subclass test not allowed for null or not null discriminator"); } AppendToken(q, discrim); } else { object constant; string fieldName = null; System.Type importedType = null; int indexOfDot = token.IndexOf(StringHelper.Dot); // don't even bother to do the lookups if the indexOfDot is not // greater than -1. This will save all the string modifications. // This allows us to resolve to the full type before obtaining the value e.g. FooStatus.OFF -> NHibernate.Model.FooStatus.OFF if (indexOfDot > -1) { fieldName = StringHelper.Unqualify(token); string typeName = StringHelper.Qualifier(token); importedType = helper.GetImportedClass(typeName); } if (indexOfDot > -1 && importedType != null && (constant = ReflectHelper.GetConstantValue(importedType, fieldName)) != null) { // need to get the NHibernate Type so we can convert the Enum or field from // a class into it's string representation for hql. IType type; try { type = TypeFactory.HeuristicType(constant.GetType().AssemblyQualifiedName); } catch (MappingException me) { throw new QueryException(me); } if (type == null) { throw new QueryException(string.Format("Could not determin the type of: {0}", token)); } try { AppendToken(q, ((ILiteralType)type).ObjectToSQLString(constant, q.Factory.Dialect)); } catch (Exception e) { throw new QueryException("Could not format constant value to SQL literal: " + token, e); } } else { //anything else string negatedToken = null; if (negated) { negations.TryGetValue(token.ToLowerInvariant(), out negatedToken); } if (negatedToken != null && (!betweenSpecialCase || !"or".Equals(negatedToken))) { AppendToken(q, negatedToken); } else { AppendToken(q, token); } } } } }