Example #1
0
        public SqlLoader(string[] aliases, ISqlLoadable[] persisters, ISessionFactoryImplementor factory, string sqlQuery, ICollection additionalQuerySpaces)
            : base(factory.Dialect)
        {
            this.sqlQuery = sqlQuery;
            this.aliases  = aliases;

            // Remember the factory for the PopulateSqlString call.
            this.factory = factory;

            alias2Persister = new Hashtable();
            ArrayList resultTypeList = new ArrayList();

            for (int i = 0; i < persisters.Length; i++)
            {
                ISqlLoadable persister = persisters[i];
                alias2Persister.Add(aliases[i], persister);
                // TODO: Does not consider any other tables referenced in the query
                querySpaces.AddAll(persister.PropertySpaces);
                resultTypeList.Add(persister.Type);
            }

            if (additionalQuerySpaces != null)
            {
                querySpaces.AddAll(additionalQuerySpaces);
            }
            resultTypes = ( IType[] )resultTypeList.ToArray(typeof(IType));

            RenderStatement(persisters);

            PostInstantiate();
        }
		public SqlLoader( string[ ] aliases, ISqlLoadable[ ] persisters, ISessionFactoryImplementor factory, string sqlQuery, ICollection additionalQuerySpaces )
			: base( factory.Dialect )
		{
			this.sqlQuery = sqlQuery;
			this.aliases = aliases;

			// Remember the factory for the PopulateSqlString call.
			this.factory = factory;

			alias2Persister = new Hashtable();
			ArrayList resultTypeList = new ArrayList();

			for( int i = 0; i < persisters.Length; i++ )
			{
				ISqlLoadable persister = persisters[ i ];
				alias2Persister.Add( aliases[ i ], persister );
				// TODO: Does not consider any other tables referenced in the query
				querySpaces.AddAll( persister.PropertySpaces );
				resultTypeList.Add( persister.Type );
			}

			if( additionalQuerySpaces != null )
			{
				querySpaces.AddAll( additionalQuerySpaces );
			}
			resultTypes = ( IType[ ] ) resultTypeList.ToArray( typeof( IType ) );

			RenderStatement( persisters );

			PostInstantiate();
		}
Example #3
0
        private string ResolveCollectionProperties(
            string aliasName,
            string propertyName,
            IDictionary fieldResults,
            ISqlLoadable elementPersister,
            ISqlLoadableCollection currentPersister,
            string suffix,
            string persisterSuffix)
        {
            if ("*".Equals(propertyName))
            {
                if (fieldResults.Count > 0)
                {
                    throw new QueryException("Using return-propertys together with * syntax is not supported.");
                }

                string selectFragment = currentPersister.SelectFragment(aliasName, suffix);
                aliasesFound++;
                return selectFragment
                       + ", "
                       + ResolveProperties(aliasName, propertyName, fieldResults, elementPersister, persisterSuffix);
            }
            else if ("element.*".Equals(propertyName))
            {
                return ResolveProperties(aliasName, "*", fieldResults, elementPersister, persisterSuffix);
            }
            else
            {
                string[] columnAliases;

                // Let return-propertys override whatever the persister has for aliases.
                columnAliases = (string[]) fieldResults[propertyName];
                if (columnAliases == null)
                {
                    columnAliases = currentPersister.GetCollectionPropertyColumnAliases(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];
            }
        }
        private void AddPersister(string alias, IDictionary <string, string[]> propertyResult, ISqlLoadable persister)
        {
            alias2Persister[alias] = persister;
            string suffix = GenerateEntitySuffix();

            log.Debug("mapping alias [{0}] to entity-suffix [{1}]", alias, suffix);
            alias2Suffix[alias]             = suffix;
            entityPropertyResultMaps[alias] = propertyResult;
        }
        private void ProcessRootReturn(NativeSQLQueryRootReturn rootReturn)
        {
            if (alias2Persister.ContainsKey(rootReturn.Alias))
            {
                // already been processed...
                return;
            }

            ISqlLoadable persister = GetSQLLoadable(rootReturn.ReturnEntityName);

            AddPersister(rootReturn.Alias, rootReturn.PropertyResultsMap, persister);
        }
        private void AddCollection(string role, string alias, IDictionary <string, string[]> propertyResults)
        {
            ISqlLoadableCollection collectionPersister = (ISqlLoadableCollection)Factory.GetCollectionPersister(role);

            alias2CollectionPersister[alias] = collectionPersister;
            string suffix = GenerateCollectionSuffix();

            log.Debug("mapping alias [{0}] to collection-suffix [{1}]", alias, suffix);
            alias2CollectionSuffix[alias]       = suffix;
            collectionPropertyResultMaps[alias] = propertyResults;

            if (collectionPersister.IsOneToMany)
            {
                ISqlLoadable persister = (ISqlLoadable)collectionPersister.ElementPersister;
                AddPersister(alias, Filter(propertyResults), persister);
            }
        }
Example #7
0
        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 void ProcessJoinReturn(NativeSQLQueryJoinReturn fetchReturn)
        {
            string alias = fetchReturn.Alias;

            if (alias2Persister.ContainsKey(alias) || alias2CollectionPersister.ContainsKey(alias))
            {
                // already been processed...
                return;
            }

            string ownerAlias = fetchReturn.OwnerAlias;

            // Make sure the owner alias is known...
            if (!alias2Return.ContainsKey(ownerAlias))
            {
                throw new HibernateException(string.Format("Owner alias [{0}] is unknown for alias [{1}]", ownerAlias, alias));
            }

            // If this return's alias has not been processed yet, do so b4 further processing of this return
            if (!alias2Persister.ContainsKey(ownerAlias))
            {
                ProcessReturn(alias2Return[ownerAlias]);
            }

            ISqlLoadable ownerPersister = alias2Persister[ownerAlias];
            IType        returnType     = ownerPersister.GetPropertyType(fetchReturn.OwnerProperty);

            if (returnType.IsCollectionType)
            {
                string role = ownerPersister.EntityName + '.' + fetchReturn.OwnerProperty;
                AddCollection(role, alias, fetchReturn.PropertyResultsMap);
            }
            else if (returnType.IsEntityType)
            {
                EntityType   eType            = (EntityType)returnType;
                string       returnEntityName = eType.GetAssociatedEntityName();
                ISqlLoadable persister        = GetSQLLoadable(returnEntityName);
                AddPersister(alias, fetchReturn.PropertyResultsMap, persister);
            }
        }
		public NonScalarReturn(SQLQueryContext context, bool queryHasAliases, string alias, LockMode lockMode, NonScalarReturn owner)
		{
			if (context == null)
			{
				throw new ArgumentNullException("context");
			}
			if (string.IsNullOrEmpty(alias))
			{
				throw new HibernateException("alias must be specified");
			}

			this.alias = alias;
			this.lockMode = lockMode;
			this.owner = owner;

			this.collectionPersister = context.GetCollectionPersister(alias);
			if (this.collectionPersister != null)
			{
				var collectionPropertyResultMap = context.GetCollectionPropertyResultsMap(alias);
				this.collectionAliases = queryHasAliases
					? new GeneratedCollectionAliases(collectionPropertyResultMap, this.collectionPersister, context.GetCollectionSuffix(alias))
					: (ICollectionAliases)new ColumnCollectionAliases(collectionPropertyResultMap, this.collectionPersister);
			}

			if (this.collectionPersister == null || this.CollectionPersister.ElementType.IsEntityType)
			{
				this.entityPersister = context.GetEntityPersister(alias);
				if (this.entityPersister != null)
				{
					var entityPropertyResultMap = context.GetEntityPropertyResultsMap(alias);
					this.entityAliases = queryHasAliases
						? new DefaultEntityAliases(entityPropertyResultMap, this.entityPersister, context.GetEntitySuffix(alias))
						: new ColumnEntityAliases(entityPropertyResultMap, this.entityPersister);
				}
			}
		}
		private void AddPersister(string alias, IDictionary<string, string[]> propertyResult, ISqlLoadable persister)
		{
			alias2Persister[alias] = persister;
			string suffix = GenerateEntitySuffix();
			log.Debug("mapping alias [" + alias + "] to entity-suffix [" + suffix + "]");
			alias2Suffix[alias] = suffix;
			entityPropertyResultMaps[alias] = propertyResult;
		}
Example #11
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];
            }
        }
Example #12
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());
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="sqlQuery"></param>
		/// <param name="aliases"></param>
		/// <param name="classes"></param>
		/// <param name="queryParameters"></param>
		/// <param name="querySpaces"></param>
		/// <returns></returns>
		public IList FindBySQL( string sqlQuery, string[ ] aliases, System.Type[ ] classes, QueryParameters queryParameters, ICollection querySpaces )
		{
			if( log.IsDebugEnabled )
			{
				log.Debug( "SQL Query: " + sqlQuery );
			}

			ISqlLoadable[ ] persisters = new ISqlLoadable[classes.Length];
			for( int i = 0; i < classes.Length; i++ )
			{
				persisters[ i ] = GetSqlLoadable( classes[ i ] );
			}

			// TODO: 2.1+ We could cache these
			SqlLoader loader = new SqlLoader( aliases, persisters, factory, sqlQuery, querySpaces );

			AutoFlushIfRequired( loader.QuerySpaces );

			// TODO: Do we need to use the .NET synchronised methods here?
			dontFlushFromFind++;
			try
			{
				return loader.List( this, queryParameters );
			}
			catch( HibernateException )
			{
				// Do not call Convert on HibernateExceptions
				throw;
			}
			catch( Exception sqle )
			{
				throw Convert( sqle, "error in FindBySQL" );
			}
			finally
			{
				// TODO: Do we need to use the .NET synchronised methods here?
				dontFlushFromFind--;
			}
		}