1 package org.hibernate.hql.ast.tree; 3 4 import java.util.ArrayList ; 5 import java.util.List ; 6 7 import org.hibernate.QueryException; 8 import org.hibernate.persister.entity.Queryable; 9 import org.hibernate.type.Type; 10 import org.hibernate.util.ArrayHelper; 11 12 import antlr.collections.AST; 13 14 20 public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode { 21 22 private Queryable persister; 23 private String columnSpec = ""; 24 private Type[] types; 25 26 private boolean discriminated; 27 private boolean explicitIdInsertion; 28 private boolean explicitVersionInsertion; 29 30 31 public void initialize(Queryable persister) { 32 if ( persister.isAbstract() ) { 33 throw new QueryException( "cannot insert into abstract class (no table)" ); 34 } 35 this.persister = persister; 36 initializeColumns(); 37 38 if ( getWalker().getSessionFactoryHelper().hasPhysicalDiscriminatorColumn( persister ) ) { 39 discriminated = true; 40 columnSpec += ", " + persister.getDiscriminatorColumnName(); 41 } 42 43 resetText(); 44 } 45 46 private void resetText() { 47 setText( "into " + getTableName() + " ( " + columnSpec + " )" ); 48 } 49 50 public String getTableName() { 51 return persister.getSubclassTableName( 0 ); 52 } 53 54 public Queryable getQueryable() { 55 return persister; 56 } 57 58 public String getEntityName() { 59 return persister.getEntityName(); 60 } 61 62 public Type[] getInsertionTypes() { 63 return types; 64 } 65 66 public boolean isDiscriminated() { 67 return discriminated; 68 } 69 70 public boolean isExplicitIdInsertion() { 71 return explicitIdInsertion; 72 } 73 74 public boolean isExplicitVersionInsertion() { 75 return explicitVersionInsertion; 76 } 77 78 public void prependIdColumnSpec() { 79 columnSpec = persister.getIdentifierColumnNames()[0] + ", " + columnSpec; 80 resetText(); 81 } 82 83 public void prependVersionColumnSpec() { 84 columnSpec = persister.getPropertyColumnNames( persister.getVersionProperty() )[0] + ", " + columnSpec; 85 resetText(); 86 } 87 88 public void validateTypes(SelectClause selectClause) throws QueryException { 89 Type[] selectTypes = selectClause.getQueryReturnTypes(); 90 if ( selectTypes.length != types.length ) { 91 throw new QueryException( "number of select types did not match those for insert" ); 92 } 93 94 for ( int i = 0; i < types.length; i++ ) { 95 if ( !types[i].equals( selectTypes[i] ) ) { 102 throw new QueryException( 103 "insertion type [" + types[i] + "] did not match selection type [" + 104 selectTypes[i] + "] at position " + i 105 ); 106 } 107 } 108 109 } 111 112 117 public String getDisplayText() { 118 StringBuffer buf = new StringBuffer (); 119 buf.append( "IntoClause{" ); 120 buf.append( "entityName=" ).append( getEntityName() ); 121 buf.append( ",tableName=" ).append( getTableName() ); 122 buf.append( ",columns={" ).append( columnSpec ).append( "}" ); 123 buf.append( "}" ); 124 return buf.toString(); 125 } 126 127 private void initializeColumns() { 128 AST propertySpec = getFirstChild(); 129 List types = new ArrayList (); 130 visitPropertySpecNodes( propertySpec.getFirstChild(), types ); 131 this.types = ArrayHelper.toTypeArray( types ); 132 columnSpec = columnSpec.substring( 0, columnSpec.length() - 2 ); 133 } 134 135 private void visitPropertySpecNodes(AST propertyNode, List types) { 136 if ( propertyNode == null ) { 137 return; 138 } 139 String name = propertyNode.getText(); 148 if ( isSuperclassProperty( name ) ) { 149 throw new QueryException( "INSERT statements cannot refer to superclass/joined properties [" + name + "]" ); 150 } 151 152 if ( name.equals( persister.getIdentifierPropertyName() ) ) { 153 explicitIdInsertion = true; 154 } 155 156 if ( persister.isVersioned() ) { 157 if ( name.equals( persister.getPropertyNames()[ persister.getVersionProperty() ] ) ) { 158 explicitVersionInsertion = true; 159 } 160 } 161 162 String [] columnNames = persister.toColumns( name ); 163 renderColumns( columnNames ); 164 types.add( persister.toType( name ) ); 165 166 visitPropertySpecNodes( propertyNode.getNextSibling(), types ); 168 visitPropertySpecNodes( propertyNode.getFirstChild(), types ); 169 } 170 171 private void renderColumns(String [] columnNames) { 172 for ( int i = 0; i < columnNames.length; i++ ) { 173 columnSpec += columnNames[i] + ", "; 174 } 175 } 176 177 private boolean isSuperclassProperty(String propertyName) { 178 return persister.getSubclassPropertyTableNumber( propertyName ) != 0; 190 } 191 } 192 | Popular Tags |