Source code: com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java
1 /*
2 * Copyright 2004 Clinton Begin
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.ibatis.sqlmap.engine.impl;
17
18 import com.ibatis.common.beans.Probe;
19 import com.ibatis.common.beans.ProbeFactory;
20 import com.ibatis.common.jdbc.exception.NestedSQLException;
21 import com.ibatis.common.util.PaginatedList;
22 import com.ibatis.common.util.ThrottledPool;
23 import com.ibatis.sqlmap.client.SqlMapException;
24 import com.ibatis.sqlmap.client.event.RowHandler;
25 import com.ibatis.sqlmap.engine.cache.CacheKey;
26 import com.ibatis.sqlmap.engine.cache.CacheModel;
27 import com.ibatis.sqlmap.engine.exchange.DataExchangeFactory;
28 import com.ibatis.sqlmap.engine.execution.SqlExecutor;
29 import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
30 import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
31 import com.ibatis.sqlmap.engine.mapping.statement.InsertStatement;
32 import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
33 import com.ibatis.sqlmap.engine.mapping.statement.PaginatedDataList;
34 import com.ibatis.sqlmap.engine.mapping.statement.SelectKeyStatement;
35 import com.ibatis.sqlmap.engine.scope.RequestScope;
36 import com.ibatis.sqlmap.engine.scope.SessionScope;
37 import com.ibatis.sqlmap.engine.transaction.Transaction;
38 import com.ibatis.sqlmap.engine.transaction.TransactionException;
39 import com.ibatis.sqlmap.engine.transaction.TransactionManager;
40 import com.ibatis.sqlmap.engine.transaction.TransactionState;
41 import com.ibatis.sqlmap.engine.transaction.user.UserProvidedTransaction;
42 import com.ibatis.sqlmap.engine.type.TypeHandlerFactory;
43
44 import javax.sql.DataSource;
45 import java.sql.Connection;
46 import java.sql.SQLException;
47 import java.util.HashMap;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.Map;
51
52 /**
53 * The workhorse that really runs the SQL
54 */
55 public class SqlMapExecutorDelegate {
56
57 private static final Probe PROBE = ProbeFactory.getProbe();
58
59 /**
60 * The default maximum number of requests
61 */
62 public static final int DEFAULT_MAX_REQUESTS = 512;
63 /**
64 * The default maximum number of sessions
65 */
66 public static final int DEFAULT_MAX_SESSIONS = 128;
67 /**
68 * The default maximum number of transactions
69 */
70 public static final int DEFAULT_MAX_TRANSACTIONS = 32;
71
72 private boolean lazyLoadingEnabled;
73 private boolean cacheModelsEnabled;
74 private boolean enhancementEnabled;
75
76 private int maxRequests = DEFAULT_MAX_REQUESTS;
77 private int maxSessions = DEFAULT_MAX_SESSIONS;
78 private int maxTransactions = DEFAULT_MAX_TRANSACTIONS;
79
80 private TransactionManager txManager;
81
82 private HashMap mappedStatements;
83 private HashMap cacheModels;
84 private HashMap resultMaps;
85 private HashMap parameterMaps;
86
87 private ThrottledPool requestPool;
88 private ThrottledPool sessionPool;
89
90 private SqlExecutor sqlExecutor;
91 private TypeHandlerFactory typeHandlerFactory;
92 private DataExchangeFactory dataExchangeFactory;
93
94 /**
95 * Default constructor
96 */
97 public SqlMapExecutorDelegate() {
98 mappedStatements = new HashMap();
99 cacheModels = new HashMap();
100 resultMaps = new HashMap();
101 parameterMaps = new HashMap();
102
103 requestPool = new ThrottledPool(RequestScope.class, DEFAULT_MAX_REQUESTS);
104 sessionPool = new ThrottledPool(SessionScope.class, DEFAULT_MAX_SESSIONS);
105
106 sqlExecutor = new SqlExecutor();
107 typeHandlerFactory = new TypeHandlerFactory();
108 dataExchangeFactory = new DataExchangeFactory(typeHandlerFactory);
109 }
110
111 /**
112 * Getter for the DataExchangeFactory
113 *
114 * @return - the DataExchangeFactory
115 */
116 public DataExchangeFactory getDataExchangeFactory() {
117 return dataExchangeFactory;
118 }
119
120 /**
121 * Getter for the TypeHandlerFactory
122 *
123 * @return - the TypeHandlerFactory
124 */
125 public TypeHandlerFactory getTypeHandlerFactory() {
126 return typeHandlerFactory;
127 }
128
129 /**
130 * Getter for the status of lazy loading
131 *
132 * @return - the status
133 */
134 public boolean isLazyLoadingEnabled() {
135 return lazyLoadingEnabled;
136 }
137
138 /**
139 * Turn on or off lazy loading
140 *
141 * @param lazyLoadingEnabled - the new state of caching
142 */
143 public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) {
144 this.lazyLoadingEnabled = lazyLoadingEnabled;
145 }
146
147 /**
148 * Getter for the status of caching
149 *
150 * @return - the status
151 */
152 public boolean isCacheModelsEnabled() {
153 return cacheModelsEnabled;
154 }
155
156 /**
157 * Turn on or off caching
158 *
159 * @param cacheModelsEnabled - the new state of caching
160 */
161 public void setCacheModelsEnabled(boolean cacheModelsEnabled) {
162 this.cacheModelsEnabled = cacheModelsEnabled;
163 }
164
165 /**
166 * Getter for the status of CGLib enhancements
167 *
168 * @return - the status
169 */
170 public boolean isEnhancementEnabled() {
171 return enhancementEnabled;
172 }
173
174 /**
175 * Turn on or off CGLib enhancements
176 *
177 * @param enhancementEnabled - the new state
178 */
179 public void setEnhancementEnabled(boolean enhancementEnabled) {
180 this.enhancementEnabled = enhancementEnabled;
181 }
182
183 /**
184 * Getter for the maximum number of requests
185 *
186 * @return - the maximum number of requests
187 */
188 public int getMaxRequests() {
189 return maxRequests;
190 }
191
192 /**
193 * Setter for the maximum number of requests
194 *
195 * @param maxRequests - the maximum number of requests
196 */
197 public void setMaxRequests(int maxRequests) {
198 this.maxRequests = maxRequests;
199 requestPool = new ThrottledPool(RequestScope.class, maxRequests);
200 }
201
202 /**
203 * Getter for the maximum number of sessions
204 *
205 * @return - the maximum number of sessions
206 */
207 public int getMaxSessions() {
208 return maxSessions;
209 }
210
211 /**
212 * Setter for the maximum number of sessions
213 *
214 * @param maxSessions - the maximum number of sessions
215 */
216 public void setMaxSessions(int maxSessions) {
217 this.maxSessions = maxSessions;
218 this.sessionPool = new ThrottledPool(SessionScope.class, maxSessions);
219 }
220
221 /**
222 * Getter for the the maximum number of transactions
223 *
224 * @return - the maximum number of transactions
225 */
226 public int getMaxTransactions() {
227 return maxTransactions;
228 }
229
230 /**
231 * Setter for the maximum number of transactions
232 *
233 * @param maxTransactions - the maximum number of transactions
234 */
235 public void setMaxTransactions(int maxTransactions) {
236 this.maxTransactions = maxTransactions;
237 }
238
239 /**
240 * Getter for the transaction manager
241 *
242 * @return - the transaction manager
243 */
244 public TransactionManager getTxManager() {
245 return txManager;
246 }
247
248 /**
249 * Setter for the transaction manager
250 *
251 * @param txManager - the transaction manager
252 */
253 public void setTxManager(TransactionManager txManager) {
254 this.txManager = txManager;
255 }
256
257 /**
258 * Add a mapped statement
259 *
260 * @param ms - the mapped statement to add
261 */
262 public void addMappedStatement(MappedStatement ms) {
263 if (mappedStatements.containsKey(ms.getId())) {
264 throw new SqlMapException("There is already a statement named " + ms.getId() + " in this SqlMap.");
265 }
266 ms.setBaseCacheKey(hashCode());
267 mappedStatements.put(ms.getId(), ms);
268 }
269
270 /**
271 * Get an iterator of the mapped statements
272 *
273 * @return - the iterator
274 */
275 public Iterator getMappedStatementNames() {
276 return mappedStatements.keySet().iterator();
277 }
278
279 /**
280 * Get a mappedstatement by its ID
281 *
282 * @param id - the statement ID
283 * @return - the mapped statement
284 */
285 public MappedStatement getMappedStatement(String id) {
286 MappedStatement ms = (MappedStatement) mappedStatements.get(id);
287 if (ms == null) {
288 throw new SqlMapException("There is no statement named " + id + " in this SqlMap.");
289 }
290 return ms;
291 }
292
293 /**
294 * Add a cache model
295 *
296 * @param model - the model to add
297 */
298 public void addCacheModel(CacheModel model) {
299 cacheModels.put(model.getId(), model);
300 }
301
302 /**
303 * Get an iterator of the cache models
304 *
305 * @return - the cache models
306 */
307 public Iterator getCacheModelNames() {
308 return cacheModels.keySet().iterator();
309 }
310
311 /**
312 * Get a cache model by ID
313 *
314 * @param id - the ID
315 * @return - the cache model
316 */
317 public CacheModel getCacheModel(String id) {
318 CacheModel model = (CacheModel) cacheModels.get(id);
319 if (model == null) {
320 throw new SqlMapException("There is no cache model named " + id + " in this SqlMap.");
321 }
322 return model;
323 }
324
325 /**
326 * Add a result map
327 *
328 * @param map - the result map to add
329 */
330 public void addResultMap(ResultMap map) {
331 resultMaps.put(map.getId(), map);
332 }
333
334 /**
335 * Get an iterator of the result maps
336 *
337 * @return - the result maps
338 */
339 public Iterator getResultMapNames() {
340 return resultMaps.keySet().iterator();
341 }
342
343 /**
344 * Get a result map by ID
345 *
346 * @param id - the ID
347 * @return - the result map
348 */
349 public ResultMap getResultMap(String id) {
350 ResultMap map = (ResultMap) resultMaps.get(id);
351 if (map == null) {
352 throw new SqlMapException("There is no result map named " + id + " in this SqlMap.");
353 }
354 return map;
355 }
356
357 /**
358 * Add a parameter map
359 *
360 * @param map - the map to add
361 */
362 public void addParameterMap(ParameterMap map) {
363 parameterMaps.put(map.getId(), map);
364 }
365
366 /**
367 * Get an iterator of all of the parameter maps
368 *
369 * @return - the parameter maps
370 */
371 public Iterator getParameterMapNames() {
372 return parameterMaps.keySet().iterator();
373 }
374
375 /**
376 * Get a parameter map by ID
377 *
378 * @param id - the ID
379 * @return - the parameter map
380 */
381 public ParameterMap getParameterMap(String id) {
382 ParameterMap map = (ParameterMap) parameterMaps.get(id);
383 if (map == null) {
384 throw new SqlMapException("There is no parameter map named " + id + " in this SqlMap.");
385 }
386 return map;
387 }
388
389 /**
390 * Flush all of the data caches
391 */
392 public void flushDataCache() {
393 Iterator models = cacheModels.values().iterator();
394 while (models.hasNext()) {
395 ((CacheModel) models.next()).flush();
396 }
397 }
398
399 /**
400 * Flush a single cache by ID
401 *
402 * @param id - the ID
403 */
404 public void flushDataCache(String id) {
405 CacheModel model = getCacheModel(id);
406 if (model != null) {
407 model.flush();
408 }
409 }
410
411 //-- Basic Methods
412 /**
413 * Call an insert statement by ID
414 *
415 * @param session - the session
416 * @param id - the statement ID
417 * @param param - the parameter object
418 * @return - the generated key (or null)
419 * @throws SQLException - if the insert fails
420 */
421 public Object insert(SessionScope session, String id, Object param) throws SQLException {
422 Object generatedKey = null;
423
424 MappedStatement ms = getMappedStatement(id);
425 Transaction trans = getTransaction(session);
426 boolean autoStart = trans == null;
427
428 try {
429 trans = autoStartTransaction(session, autoStart, trans);
430
431 SelectKeyStatement selectKeyStatement = null;
432 if (ms instanceof InsertStatement) {
433 selectKeyStatement = ((InsertStatement) ms).getSelectKeyStatement();
434 }
435
436 if (selectKeyStatement != null && !selectKeyStatement.isAfter()) {
437 generatedKey = executeSelectKey(session, trans, ms, param);
438 }
439
440 RequestScope request = popRequest(session, ms);
441 try {
442 ms.executeUpdate(request, trans, param);
443 } finally {
444 pushRequest(request);
445 }
446
447 if (selectKeyStatement != null && selectKeyStatement.isAfter()) {
448 generatedKey = executeSelectKey(session, trans, ms, param);
449 }
450
451 autoCommitTransaction(session, autoStart);
452 } finally {
453 autoEndTransaction(session, autoStart);
454 }
455
456 return generatedKey;
457 }
458
459 private Object executeSelectKey(SessionScope session, Transaction trans, MappedStatement ms, Object param) throws SQLException {
460 Object generatedKey = null;
461 RequestScope request;
462 InsertStatement insert = (InsertStatement) ms;
463 SelectKeyStatement selectKeyStatement = insert.getSelectKeyStatement();
464 if (selectKeyStatement != null) {
465 request = popRequest(session, selectKeyStatement);
466 try {
467 generatedKey = selectKeyStatement.executeQueryForObject(request, trans, param, null);
468 String keyProp = selectKeyStatement.getKeyProperty();
469 if (keyProp != null) {
470 PROBE.setObject(param, keyProp, generatedKey);
471 }
472 } finally {
473 pushRequest(request);
474 }
475 }
476 return generatedKey;
477 }
478
479 /**
480 * Execute an update statement
481 *
482 * @param session - the session scope
483 * @param id - the statement ID
484 * @param param - the parameter object
485 * @return - the number of rows updated
486 * @throws SQLException - if the update fails
487 */
488 public int update(SessionScope session, String id, Object param) throws SQLException {
489 int rows = 0;
490
491 MappedStatement ms = getMappedStatement(id);
492 Transaction trans = getTransaction(session);
493 boolean autoStart = trans == null;
494
495 try {
496 trans = autoStartTransaction(session, autoStart, trans);
497
498 RequestScope request = popRequest(session, ms);
499 try {
500 rows = ms.executeUpdate(request, trans, param);
501 } finally {
502 pushRequest(request);
503 }
504
505 autoCommitTransaction(session, autoStart);
506 } finally {
507 autoEndTransaction(session, autoStart);
508 }
509
510 return rows;
511 }
512
513 /**
514 * Execute a delete statement
515 *
516 * @param session - the session scope
517 * @param id - the statement ID
518 * @param param - the parameter object
519 * @return - the number of rows deleted
520 * @throws SQLException - if the delete fails
521 */
522 public int delete(SessionScope session, String id, Object param) throws SQLException {
523 return update(session, id, param);
524 }
525
526 /**
527 * Execute a select for a single object
528 *
529 * @param session - the session scope
530 * @param id - the statement ID
531 * @param paramObject - the parameter object
532 * @return - the result of the query
533 * @throws SQLException - if the query fails
534 */
535 public Object queryForObject(SessionScope session, String id, Object paramObject) throws SQLException {
536 return queryForObject(session, id, paramObject, null);
537 }
538
539 /**
540 * Execute a select for a single object
541 *
542 * @param session - the session scope
543 * @param id - the statement ID
544 * @param paramObject - the parameter object
545 * @param resultObject - the result object (if not supplied or null, a new object will be created)
546 * @return - the result of the query
547 * @throws SQLException - if the query fails
548 */
549 public Object queryForObject(SessionScope session, String id, Object paramObject, Object resultObject) throws SQLException {
550 Object object = null;
551
552 MappedStatement ms = getMappedStatement(id);
553 Transaction trans = getTransaction(session);
554 boolean autoStart = trans == null;
555
556 try {
557 trans = autoStartTransaction(session, autoStart, trans);
558
559 RequestScope request = popRequest(session, ms);
560 try {
561 object = ms.executeQueryForObject(request, trans, paramObject, resultObject);
562 } finally {
563 pushRequest(request);
564 }
565
566 autoCommitTransaction(session, autoStart);
567 } finally {
568 autoEndTransaction(session, autoStart);
569 }
570
571 return object;
572 }
573
574 /**
575 * Execute a query for a list
576 *
577 * @param session - the session scope
578 * @param id - the statement ID
579 * @param paramObject - the parameter object
580 * @return - the data list
581 * @throws SQLException - if the query fails
582 */
583 public List queryForList(SessionScope session, String id, Object paramObject) throws SQLException {
584 return queryForList(session, id, paramObject, SqlExecutor.NO_SKIPPED_RESULTS, SqlExecutor.NO_MAXIMUM_RESULTS);
585 }
586
587 /**
588 * Execute a query for a list
589 *
590 * @param session - the session scope
591 * @param id - the statement ID
592 * @param paramObject - the parameter object
593 * @param skip - the number of rows to skip
594 * @param max - the maximum number of rows to return
595 * @return - the data list
596 * @throws SQLException - if the query fails
597 */
598 public List queryForList(SessionScope session, String id, Object paramObject, int skip, int max) throws SQLException {
599 List list = null;
600
601 MappedStatement ms = getMappedStatement(id);
602 Transaction trans = getTransaction(session);
603 boolean autoStart = trans == null;
604
605 try {
606 trans = autoStartTransaction(session, autoStart, trans);
607
608 RequestScope request = popRequest(session, ms);
609 try {
610 list = ms.executeQueryForList(request, trans, paramObject, skip, max);
611 } finally {
612 pushRequest(request);
613 }
614
615 autoCommitTransaction(session, autoStart);
616 } finally {
617 autoEndTransaction(session, autoStart);
618 }
619
620 return list;
621 }
622
623 /**
624 * Execute a query with a row handler.
625 * The row handler is called once per row in the query results.
626 *
627 * @param session - the session scope
628 * @param id - the statement ID
629 * @param paramObject - the parameter object
630 * @param rowHandler - the row handler
631 * @throws SQLException - if the query fails
632 */
633 public void queryWithRowHandler(SessionScope session, String id, Object paramObject, RowHandler rowHandler) throws SQLException {
634
635 MappedStatement ms = getMappedStatement(id);
636 Transaction trans = getTransaction(session);
637 boolean autoStart = trans == null;
638
639 try {
640 trans = autoStartTransaction(session, autoStart, trans);
641
642 RequestScope request = popRequest(session, ms);
643 try {
644 ms.executeQueryWithRowHandler(request, trans, paramObject, rowHandler);
645 } finally {
646 pushRequest(request);
647 }
648
649 autoCommitTransaction(session, autoStart);
650 } finally {
651 autoEndTransaction(session, autoStart);
652 }
653
654 }
655
656 /**
657 * Execute a query and return a paginated list
658 *
659 * @param session - the session scope
660 * @param id - the statement ID
661 * @param paramObject - the parameter object
662 * @param pageSize - the page size
663 * @return - the data list
664 * @throws SQLException - if the query fails
665 */
666 public PaginatedList queryForPaginatedList(SessionScope session, String id, Object paramObject, int pageSize) throws SQLException {
667 return new PaginatedDataList(session.getSqlMapExecutor(), id, paramObject, pageSize);
668 }
669
670 /**
671 * Execute a query for a map.
672 * The map has the table key as the key, and the results as the map data
673 *
674 * @param session - the session scope
675 * @param id - the statement ID
676 * @param paramObject - the parameter object
677 * @param keyProp - the key property (from the results for the map)
678 * @return - the Map
679 * @throws SQLException - if the query fails
680 */
681 public Map queryForMap(SessionScope session, String id, Object paramObject, String keyProp) throws SQLException {
682 return queryForMap(session, id, paramObject, keyProp, null);
683 }
684
685 /**
686 * Execute a query for a map.
687 * The map has the table key as the key, and a property from the results as the map data
688 *
689 * @param session - the session scope
690 * @param id - the statement ID
691 * @param paramObject - the parameter object
692 * @param keyProp - the property for the map key
693 * @param valueProp - the property for the map data
694 * @return - the Map
695 * @throws SQLException - if the query fails
696 */
697 public Map queryForMap(SessionScope session, String id, Object paramObject, String keyProp, String valueProp) throws SQLException {
698 Map map = new HashMap();
699
700 List list = queryForList(session, id, paramObject);
701
702 for (int i = 0, n = list.size(); i < n; i++) {
703 Object object = list.get(i);
704 Object key = PROBE.getObject(object, keyProp);
705 Object value = null;
706 if (valueProp == null) {
707 value = object;
708 } else {
709 value = PROBE.getObject(object, valueProp);
710 }
711 map.put(key, value);
712 }
713
714 return map;
715 }
716
717 // -- Transaction Control Methods
718 /**
719 * Start a transaction on the session
720 *
721 * @param session - the session
722 * @throws SQLException - if the transaction could not be started
723 */
724 public void startTransaction(SessionScope session) throws SQLException {
725 try {
726 txManager.begin(session);
727 } catch (TransactionException e) {
728 throw new NestedSQLException("Could not start transaction. Cause: " + e, e);
729 }
730 }
731
732 /**
733 * Start a transaction on the session with the specified isolation level.
734 *
735 * @param session - the session
736 * @throws SQLException - if the transaction could not be started
737 */
738 public void startTransaction(SessionScope session, int transactionIsolation) throws SQLException {
739 try {
740 txManager.begin(session, transactionIsolation);
741 } catch (TransactionException e) {
742 throw new NestedSQLException("Could not start transaction. Cause: " + e, e);
743 }
744 }
745
746 /**
747 * Commit the transaction on a session
748 *
749 * @param session - the session
750 * @throws SQLException - if the transaction could not be committed
751 */
752 public void commitTransaction(SessionScope session) throws SQLException {
753 try {
754 // Auto batch execution
755 if (session.isInBatch()) {
756 executeBatch(session);
757 }
758 sqlExecutor.cleanup(session);
759 txManager.commit(session);
760 } catch (TransactionException e) {
761 throw new NestedSQLException("Could not commit transaction. Cause: " + e, e);
762 }
763 }
764
765 /**
766 * End the transaction on a session
767 *
768 * @param session - the session
769 * @throws SQLException - if the transaction could not be ended
770 */
771 public void endTransaction(SessionScope session) throws SQLException {
772 try {
773 try {
774 sqlExecutor.cleanup(session);
775 } finally {
776 txManager.end(session);
777 }
778 } catch (TransactionException e) {
779 throw new NestedSQLException("Error while ending transaction. Cause: " + e, e);
780 }
781 }
782
783 /**
784 * Start a batch for a session
785 *
786 * @param session - the session
787 */
788 public void startBatch(SessionScope session) {
789 session.setInBatch(true);
790 }
791
792 /**
793 * Execute a batch for a session
794 *
795 * @param session - the session
796 * @return - the number of rows impacted by the batch
797 * @throws SQLException - if the batch fails
798 */
799 public int executeBatch(SessionScope session) throws SQLException {
800 session.setInBatch(false);
801 return sqlExecutor.executeBatch(session);
802 }
803
804 /**
805 * Use a user-provided transaction for a session
806 *
807 * @param session - the session scope
808 * @param userConnection - the user supplied connection
809 */
810 public void setUserProvidedTransaction(SessionScope session, Connection userConnection) {
811 if (session.getTransactionState() == TransactionState.STATE_USER_PROVIDED) {
812 session.recallTransactionState();
813 }
814 if (userConnection != null) {
815 Connection conn = userConnection;
816 session.saveTransactionState();
817 session.setTransaction(new UserProvidedTransaction(conn));
818 session.setTransactionState(TransactionState.STATE_USER_PROVIDED);
819 } else {
820 session.setTransaction(null);
821 pushSession(session);
822 }
823 }
824 /**
825 * Get the DataSource for the session
826 *
827 * @return - the DataSource
828 */
829 public DataSource getDataSource() {
830 DataSource ds = null;
831 if (txManager != null) {
832 ds = txManager.getDataSource();
833 }
834 return ds;
835 }
836
837 /**
838 * Getter for the SqlExecutor
839 *
840 * @return the SqlExecutor
841 */
842 public SqlExecutor getSqlExecutor() {
843 return sqlExecutor;
844 }
845
846 /**
847 * Get a transaction for the session
848 *
849 * @param session - the session
850 * @return - the transaction
851 */
852 public Transaction getTransaction(SessionScope session) {
853 return session.getTransaction();
854 }
855
856 // -- Private Methods
857
858 private void autoEndTransaction(SessionScope session, boolean autoStart) throws SQLException {
859 if (autoStart) {
860 session.getSqlMapTxMgr().endTransaction();
861 }
862 }
863
864 private void autoCommitTransaction(SessionScope session, boolean autoStart) throws SQLException {
865 if (autoStart) {
866 session.getSqlMapTxMgr().commitTransaction();
867 }
868 }
869
870 private Transaction autoStartTransaction(SessionScope session, boolean autoStart, Transaction trans) throws SQLException {
871 Transaction transaction = trans;
872 if (autoStart) {
873 session.getSqlMapTxMgr().startTransaction();
874 transaction = getTransaction(session);
875 }
876 return transaction;
877 }
878
879 public boolean equals(Object obj) {
880 return this == obj;
881 }
882
883 public int hashCode() {
884 CacheKey key = new CacheKey();
885 if (txManager != null) {
886 key.update(txManager);
887 if (txManager.getDataSource() != null) {
888 key.update(txManager.getDataSource());
889 }
890 }
891 key.update(System.identityHashCode(this));
892 return key.hashCode();
893 }
894
895 protected RequestScope popRequest(SessionScope session, MappedStatement mappedStatement) {
896 RequestScope request = (RequestScope) requestPool.pop();
897 session.incrementRequestStackDepth();
898 request.setSession(session);
899 mappedStatement.initRequest(request);
900 return request;
901 }
902
903 protected void pushRequest(RequestScope request) {
904 request.getSession().decrementRequestStackDepth();
905 request.reset();
906 requestPool.push(request);
907 }
908
909 protected SessionScope popSession() {
910 return (SessionScope) sessionPool.pop();
911 }
912
913 protected void pushSession(SessionScope session) {
914 session.reset();
915 sessionPool.push(session);
916 }
917
918 }
919