⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intoclause.java

📁 hibernate 开源框架的代码 jar包希望大家能喜欢
💻 JAVA
字号:
// $Id: IntoClause.java 8050 2005-08-31 15:02:23Z steveebersole $package org.hibernate.hql.ast.tree;import java.util.ArrayList;import java.util.List;import java.sql.Types;import org.hibernate.QueryException;import org.hibernate.persister.entity.Queryable;import org.hibernate.type.Type;import org.hibernate.util.ArrayHelper;import antlr.collections.AST;/** * Represents an entity referenced in the INTO clause of an HQL * INSERT statement. * * @author Steve Ebersole */public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {	private Queryable persister;	private String columnSpec = "";	private Type[] types;	private boolean discriminated;	private boolean explicitIdInsertion;	private boolean explicitVersionInsertion;	public void initialize(Queryable persister) {		if ( persister.isAbstract() ) {			throw new QueryException( "cannot insert into abstract class (no table)" );		}		this.persister = persister;		initializeColumns();		if ( getWalker().getSessionFactoryHelper().hasPhysicalDiscriminatorColumn( persister ) ) {			discriminated = true;			columnSpec += ", " + persister.getDiscriminatorColumnName();		}		resetText();	}	private void resetText() {		setText( "into " + getTableName() + " ( " + columnSpec + " )" );	}	public String getTableName() {		return persister.getSubclassTableName( 0 );	}	public Queryable getQueryable() {		return persister;	}	public String getEntityName() {		return persister.getEntityName();	}	public Type[] getInsertionTypes() {		return types;	}	public boolean isDiscriminated() {		return discriminated;	}	public boolean isExplicitIdInsertion() {		return explicitIdInsertion;	}	public boolean isExplicitVersionInsertion() {		return explicitVersionInsertion;	}	public void prependIdColumnSpec() {		columnSpec = persister.getIdentifierColumnNames()[0] + ", " + columnSpec;		resetText();	}	public void prependVersionColumnSpec() {		columnSpec = persister.getPropertyColumnNames( persister.getVersionProperty() )[0] + ", " + columnSpec;		resetText();	}	public void validateTypes(SelectClause selectClause) throws QueryException {		Type[] selectTypes = selectClause.getQueryReturnTypes();		if ( selectTypes.length != types.length ) {			throw new QueryException( "number of select types did not match those for insert" );		}		for ( int i = 0; i < types.length; i++ ) {			if ( !areCompatible( types[i], selectTypes[i] ) ) {				throw new QueryException(				        "insertion type [" + types[i] + "] and selection type [" +				        selectTypes[i] + "] at position " + i + " are not compatible"				);			}		}		// otherwise, everything ok.	}	/**	 * Returns additional display text for the AST node.	 *	 * @return String - The additional display text.	 */	public String getDisplayText() {		StringBuffer buf = new StringBuffer();		buf.append( "IntoClause{" );		buf.append( "entityName=" ).append( getEntityName() );		buf.append( ",tableName=" ).append( getTableName() );		buf.append( ",columns={" ).append( columnSpec ).append( "}" );		buf.append( "}" );		return buf.toString();	}	private void initializeColumns() {		AST propertySpec = getFirstChild();		List types = new ArrayList();		visitPropertySpecNodes( propertySpec.getFirstChild(), types );		this.types = ArrayHelper.toTypeArray( types );		columnSpec = columnSpec.substring( 0, columnSpec.length() - 2 );	}	private void visitPropertySpecNodes(AST propertyNode, List types) {		if ( propertyNode == null ) {			return;		}		// TODO : we really need to be able to deal with component paths here also;		// this is difficult because the hql-sql grammar expects all those node types		// to be FromReferenceNodes.  One potential fix here would be to convert the		// IntoClause to just use a FromClause/FromElement combo (as a child of the		// InsertStatement) and move all this logic into the InsertStatement.  That's		// probably the easiest approach (read: least amount of changes to the grammar		// and code), but just doesn't feel right as then an insert would contain		// 2 from-clauses		String name = propertyNode.getText();		if ( isSuperclassProperty( name ) ) {			throw new QueryException( "INSERT statements cannot refer to superclass/joined properties [" + name + "]" );		}		if ( name.equals( persister.getIdentifierPropertyName() ) ) {			explicitIdInsertion = true;		}		if ( persister.isVersioned() ) {			if ( name.equals( persister.getPropertyNames()[ persister.getVersionProperty() ] ) ) {				explicitVersionInsertion = true;			}		}		String[] columnNames = persister.toColumns( name );		renderColumns( columnNames );		types.add( persister.toType( name ) );		// visit width-first, then depth		visitPropertySpecNodes( propertyNode.getNextSibling(), types );		visitPropertySpecNodes( propertyNode.getFirstChild(), types );	}	private void renderColumns(String[] columnNames) {		for ( int i = 0; i < columnNames.length; i++ ) {			columnSpec += columnNames[i] + ", ";		}	}	private boolean isSuperclassProperty(String propertyName) {		// really there are two situations where it should be ok to allow the insertion		// into properties defined on a superclass:		//      1) union-subclass with an abstract root entity		//      2) discrim-subclass		//		// #1 is handled already because of the fact that		// UnionSubclassPersister alreay always returns 0		// for this call...		//		// we may want to disallow it for discrim-subclass just for		// consistency-sake (currently does not work anyway)...		return persister.getSubclassPropertyTableNumber( propertyName ) != 0;	}	/**	 * Determine whether the two types are "assignment compatible".	 *	 * @param target The type defined in the into-clause.	 * @param source The type defined in the select clause.	 * @return True if they are assignment compatible.	 */	private boolean areCompatible(Type target, Type source) {		if ( target.equals( source ) ) {			// if the types report logical equivalence, return true...			return true;		}		// otherwise, perform a "deep equivalence" check...		if ( !target.getReturnedClass().isAssignableFrom( source.getReturnedClass() ) ) {			return false;		}		int[] targetDatatypes = target.sqlTypes( getSessionFactoryHelper().getFactory() );		int[] sourceDatatypes = source.sqlTypes( getSessionFactoryHelper().getFactory() );		if ( targetDatatypes.length != sourceDatatypes.length ) {			return false;		}		for ( int i = 0; i < targetDatatypes.length; i++ ) {			if ( !areSqlTypesCompatible( targetDatatypes[i], sourceDatatypes[i] ) ) {				return false;			}		}		return true;	}	private boolean areSqlTypesCompatible(int target, int source) {		switch ( target ) {			case Types.TIMESTAMP:				return source == Types.DATE || source == Types.TIME || source == Types.TIMESTAMP;			case Types.DATE:				return source == Types.DATE || source == Types.TIMESTAMP;			case Types.TIME:				return source == Types.TIME || source == Types.TIMESTAMP;			default:				return target == source;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -