~ubuntu-branches/ubuntu/wily/libhibernate3-java/wily-proposed

« back to all changes in this revision

Viewing changes to src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2007-10-14 14:43:34 UTC
  • Revision ID: james.westby@ubuntu.com-20071014144334-eamc8i0q10gs1aro
Tags: upstream-3.2.5
ImportĀ upstreamĀ versionĀ 3.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// $Id: AbstractStatementExecutor.java 11287 2007-03-15 11:38:25Z steve.ebersole@jboss.com $
 
2
package org.hibernate.hql.ast.exec;
 
3
 
 
4
import java.sql.PreparedStatement;
 
5
import java.sql.Connection;
 
6
import java.sql.Statement;
 
7
 
 
8
import org.hibernate.HibernateException;
 
9
import org.hibernate.action.BulkOperationCleanupAction;
 
10
import org.hibernate.engine.SessionFactoryImplementor;
 
11
import org.hibernate.engine.SessionImplementor;
 
12
import org.hibernate.engine.transaction.Isolater;
 
13
import org.hibernate.engine.transaction.IsolatedWork;
 
14
import org.hibernate.event.EventSource;
 
15
import org.hibernate.hql.ast.HqlSqlWalker;
 
16
import org.hibernate.hql.ast.SqlGenerator;
 
17
import org.hibernate.persister.entity.Queryable;
 
18
import org.hibernate.sql.InsertSelect;
 
19
import org.hibernate.sql.Select;
 
20
import org.hibernate.sql.SelectFragment;
 
21
import org.hibernate.util.StringHelper;
 
22
 
 
23
import antlr.RecognitionException;
 
24
import antlr.collections.AST;
 
25
 
 
26
import org.apache.commons.logging.Log;
 
27
 
 
28
/**
 
29
 * Implementation of AbstractStatementExecutor.
 
30
 *
 
31
 * @author Steve Ebersole
 
32
 */
 
33
public abstract class AbstractStatementExecutor implements StatementExecutor {
 
34
 
 
35
        private final Log log;
 
36
        private final HqlSqlWalker walker;
 
37
 
 
38
        public AbstractStatementExecutor(HqlSqlWalker walker, Log log) {
 
39
                this.walker = walker;
 
40
                this.log = log;
 
41
        }
 
42
 
 
43
        protected HqlSqlWalker getWalker() {
 
44
                return walker;
 
45
        }
 
46
 
 
47
        protected SessionFactoryImplementor getFactory() {
 
48
                return walker.getSessionFactoryHelper().getFactory();
 
49
        }
 
50
 
 
51
        protected abstract Queryable[] getAffectedQueryables();
 
52
 
 
53
        protected String generateIdInsertSelect(Queryable persister, String tableAlias, AST whereClause) {
 
54
                Select select = new Select( getFactory().getDialect() );
 
55
                SelectFragment selectFragment = new SelectFragment()
 
56
                                .addColumns( tableAlias, persister.getIdentifierColumnNames(), persister.getIdentifierColumnNames() );
 
57
                select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
 
58
 
 
59
                String rootTableName = persister.getTableName();
 
60
                String fromJoinFragment = persister.fromJoinFragment( tableAlias, true, false );
 
61
                String whereJoinFragment = persister.whereJoinFragment( tableAlias, true, false );
 
62
 
 
63
                select.setFromClause( rootTableName + ' ' + tableAlias + fromJoinFragment );
 
64
 
 
65
                if ( whereJoinFragment == null ) {
 
66
                        whereJoinFragment = "";
 
67
                }
 
68
                else {
 
69
                        whereJoinFragment = whereJoinFragment.trim();
 
70
                        if ( whereJoinFragment.startsWith( "and" ) ) {
 
71
                                whereJoinFragment = whereJoinFragment.substring( 4 );
 
72
                        }
 
73
                }
 
74
 
 
75
                String userWhereClause = "";
 
76
                if ( whereClause.getNumberOfChildren() != 0 ) {
 
77
                        // If a where clause was specified in the update/delete query, use it to limit the
 
78
                        // returned ids here...
 
79
                        try {
 
80
                                SqlGenerator sqlGenerator = new SqlGenerator( getFactory() );
 
81
                                sqlGenerator.whereClause( whereClause );
 
82
                                userWhereClause = sqlGenerator.getSQL().substring( 7 );  // strip the " where "
 
83
                        }
 
84
                        catch ( RecognitionException e ) {
 
85
                                throw new HibernateException( "Unable to generate id select for DML operation", e );
 
86
                        }
 
87
                        if ( whereJoinFragment.length() > 0 ) {
 
88
                                whereJoinFragment += " and ";
 
89
                        }
 
90
                }
 
91
 
 
92
                select.setWhereClause( whereJoinFragment + userWhereClause );
 
93
 
 
94
                InsertSelect insert = new InsertSelect( getFactory().getDialect() );
 
95
                if ( getFactory().getSettings().isCommentsEnabled() ) {
 
96
                        insert.setComment( "insert-select for " + persister.getEntityName() + " ids" );
 
97
                }
 
98
                insert.setTableName( persister.getTemporaryIdTableName() );
 
99
                insert.setSelect( select );
 
100
                return insert.toStatementString();
 
101
        }
 
102
 
 
103
        protected String generateIdSubselect(Queryable persister) {
 
104
                return "select " + StringHelper.join( ", ", persister.getIdentifierColumnNames() ) +
 
105
                                " from " + persister.getTemporaryIdTableName();
 
106
        }
 
107
 
 
108
        protected void createTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
 
109
                // Don't really know all the codes required to adequately decipher returned jdbc exceptions here.
 
110
                // simply allow the failure to be eaten and the subsequent insert-selects/deletes should fail
 
111
                IsolatedWork work = new IsolatedWork() {
 
112
                        public void doWork(Connection connection) throws HibernateException {
 
113
                                Statement stmnt = null;
 
114
                                try {
 
115
                                        stmnt = connection.createStatement();
 
116
                                        stmnt.executeUpdate( persister.getTemporaryIdTableDDL() );
 
117
                                }
 
118
                                catch( Throwable t ) {
 
119
                                        log.debug( "unable to create temporary id table [" + t.getMessage() + "]" );
 
120
                                }
 
121
                                finally {
 
122
                                        if ( stmnt != null ) {
 
123
                                                try {
 
124
                                                        stmnt.close();
 
125
                                                }
 
126
                                                catch( Throwable ignore ) {
 
127
                                                        // ignore
 
128
                                                }
 
129
                                        }
 
130
                                }
 
131
                        }
 
132
                };
 
133
                if ( shouldIsolateTemporaryTableDDL() ) {
 
134
                        if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
 
135
                                Isolater.doIsolatedWork( work, session );
 
136
                        }
 
137
                        else {
 
138
                                Isolater.doNonTransactedWork( work, session );
 
139
                        }
 
140
                }
 
141
                else {
 
142
                        work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
 
143
                        session.getJDBCContext().getConnectionManager().afterStatement();
 
144
                }
 
145
        }
 
146
 
 
147
        protected void dropTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
 
148
                if ( getFactory().getDialect().dropTemporaryTableAfterUse() ) {
 
149
                        IsolatedWork work = new IsolatedWork() {
 
150
                                public void doWork(Connection connection) throws HibernateException {
 
151
                                        Statement stmnt = null;
 
152
                                        try {
 
153
                                                stmnt = connection.createStatement();
 
154
                                                stmnt.executeUpdate( "drop table " + persister.getTemporaryIdTableName() );
 
155
                                        }
 
156
                                        catch( Throwable t ) {
 
157
                                                log.warn( "unable to drop temporary id table after use [" + t.getMessage() + "]" );
 
158
                                        }
 
159
                                        finally {
 
160
                                                if ( stmnt != null ) {
 
161
                                                        try {
 
162
                                                                stmnt.close();
 
163
                                                        }
 
164
                                                        catch( Throwable ignore ) {
 
165
                                                                // ignore
 
166
                                                        }
 
167
                                                }
 
168
                                        }
 
169
                                }
 
170
                        };
 
171
 
 
172
                        if ( shouldIsolateTemporaryTableDDL() ) {
 
173
                                if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
 
174
                                        Isolater.doIsolatedWork( work, session );
 
175
                                }
 
176
                                else {
 
177
                                        Isolater.doNonTransactedWork( work, session );
 
178
                                }
 
179
                        }
 
180
                        else {
 
181
                                work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
 
182
                                session.getJDBCContext().getConnectionManager().afterStatement();
 
183
                        }
 
184
                }
 
185
                else {
 
186
                        // at the very least cleanup the data :)
 
187
                        PreparedStatement ps = null;
 
188
                        try {
 
189
                                ps = session.getBatcher().prepareStatement( "delete from " + persister.getTemporaryIdTableName() );
 
190
                                ps.executeUpdate();
 
191
                        }
 
192
                        catch( Throwable t ) {
 
193
                                log.warn( "unable to cleanup temporary id table after use [" + t + "]" );
 
194
                        }
 
195
                        finally {
 
196
                                if ( ps != null ) {
 
197
                                        try {
 
198
                                                session.getBatcher().closeStatement( ps );
 
199
                                        }
 
200
                                        catch( Throwable ignore ) {
 
201
                                                // ignore
 
202
                                        }
 
203
                                }
 
204
                        }
 
205
                }
 
206
        }
 
207
 
 
208
        protected void coordinateSharedCacheCleanup(SessionImplementor session) {
 
209
                BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getAffectedQueryables() );
 
210
 
 
211
                action.init();
 
212
 
 
213
                if ( session.isEventSource() ) {
 
214
                        ( ( EventSource ) session ).getActionQueue().addAction( action );
 
215
                }
 
216
        }
 
217
 
 
218
        protected boolean shouldIsolateTemporaryTableDDL() {
 
219
                Boolean dialectVote = getFactory().getDialect().performTemporaryTableDDLInIsolation();
 
220
                if ( dialectVote != null ) {
 
221
                        return dialectVote.booleanValue();
 
222
                }
 
223
                else {
 
224
                        return getFactory().getSettings().isDataDefinitionImplicitCommit();
 
225
                }
 
226
        }
 
227
}