OSDN Git Service

"https://svn.sourceforge.jp/svnroot/ea2ddl" にプロジェクト "ea2ddl-dao" を共用
[ea2ddl/ea2ddl.git] / ea2ddl-dao / src / main / java / jp / sourceforge / ea2ddl / dao / allcommon / s2dao / FetchNarrowingResultSetWrapper.java
1 package jp.sourceforge.ea2ddl.dao.allcommon.s2dao;\r
2 \r
3 import java.sql.ResultSet;\r
4 import java.sql.Statement;\r
5 import java.sql.SQLException;\r
6 \r
7 import org.seasar.extension.jdbc.impl.ResultSetWrapper;\r
8 \r
9 import jp.sourceforge.ea2ddl.dao.allcommon.cbean.FetchNarrowingBean;\r
10 import jp.sourceforge.ea2ddl.dao.allcommon.s2dao.internal.sqlhandler.InternalBasicHandler.SQLExceptionHandler;\r
11 \r
12 /**\r
13  * The wrapper of fetch narrowing result set.\r
14  * @author DBFlute(AutoGenerator)\r
15  */\r
16 public class FetchNarrowingResultSetWrapper extends ResultSetWrapper {\r
17 \r
18     // ===================================================================================\r
19     //                                                                           Attribute\r
20     //                                                                           =========\r
21     /** The real result set. (NotNull) */\r
22     protected ResultSet _resultSet;\r
23 \r
24     /** The bean of fetch narrowing. (NotNull) */\r
25     protected FetchNarrowingBean _fetchNarrowingBean;\r
26 \r
27     /** The counter of fetch. */\r
28     protected long _fetchCounter;\r
29 \r
30     /** the counter of request. */\r
31     protected long _requestCounter;\r
32 \r
33     /** Does it offset by cursor forcedly? */\r
34     protected boolean _offsetByCursorForcedly;\r
35 \r
36     /** Does it limit by cursor forcedly? */\r
37     protected boolean _limitByCursorForcedly;\r
38         \r
39         /** Does it skip to cursor end? */\r
40         protected boolean _skipToCursorEnd;\r
41 \r
42     // ===================================================================================\r
43     //                                                                         Constructor\r
44     //                                                                         ===========\r
45     /**\r
46      * Constructor.\r
47      * @param resultSet Original result set. (NotNull)\r
48      * @param fetchNarrowingBean Fetch-narrowing-bean. (NotNull)\r
49      * @param offsetByCursorForcedly Offset by cursor forcedly.\r
50      * @param limitByCursorForcedly Limit by cursor forcedly.\r
51      */\r
52     public FetchNarrowingResultSetWrapper(ResultSet resultSet, FetchNarrowingBean fetchNarrowingBean\r
53                                              , boolean offsetByCursorForcedly, boolean limitByCursorForcedly) {\r
54         super(resultSet);\r
55 \r
56         _resultSet = resultSet;\r
57         _fetchNarrowingBean = fetchNarrowingBean;\r
58         _offsetByCursorForcedly = offsetByCursorForcedly;\r
59         _limitByCursorForcedly = limitByCursorForcedly;\r
60 \r
61         skip();\r
62     }\r
63 \r
64     // ===================================================================================\r
65     //                                                                                Skip\r
66     //                                                                                ====\r
67     /**\r
68      * Skip to start-index.\r
69      */\r
70     protected void skip() {\r
71         if (!isAvailableSkipRecord()) {\r
72             return;\r
73         }\r
74         final int skipStartIndex = getFetchNarrowingSkipStartIndex();\r
75         if (isScrollableCursor()) {\r
76             try {\r
77                 if (0 == skipStartIndex) {\r
78                     _resultSet.beforeFirst();\r
79                 } else {\r
80                     _resultSet.absolute(skipStartIndex);\r
81                 }\r
82                 _fetchCounter = _resultSet.getRow();\r
83             } catch (SQLException e) {\r
84                 handleSQLException(e, null);\r
85             }\r
86         } else {\r
87             try {\r
88                 while (true) {\r
89                                         if (_fetchCounter >= skipStartIndex) {\r
90                                             break;\r
91                                         }\r
92                                         if (!_resultSet.next()) {\r
93                                             _skipToCursorEnd = true;// [DBFLUTE-243]\r
94                                             break;\r
95                                         }\r
96                     ++_fetchCounter;\r
97                 }\r
98             } catch (SQLException e) {\r
99                 handleSQLException(e, null);\r
100             }\r
101         }\r
102     }\r
103 \r
104     protected boolean isAvailableSkipRecord() {\r
105         if (!isFetchNarrowingEffective()) {\r
106             return false;\r
107         }\r
108         if (isOffsetByCursorForcedly()) {\r
109             return true;\r
110         }\r
111         if (isFetchNarrowingSkipStartIndexEffective()) {\r
112             return true;\r
113         }\r
114         return false;\r
115     }\r
116 \r
117     // ===================================================================================\r
118     //                                                                                Next\r
119     //                                                                                ====\r
120     /**\r
121      * Next.\r
122      * @return Does the result set have next record?\r
123      * @throws SQLException\r
124      */\r
125     public boolean next() throws SQLException {\r
126         final boolean hasNext = super.next();\r
127         ++_requestCounter;\r
128         if (!isAvailableLimitLoopCount()) {\r
129             checkSafetyResult(hasNext);\r
130             return hasNext;\r
131         }\r
132 \r
133         if (hasNext && _fetchCounter < getFetchNarrowingSkipStartIndex() + getFetchNarrowingLoopCount()) {\r
134             ++_fetchCounter;\r
135             checkSafetyResult(true);\r
136             return true;\r
137         } else {\r
138             return false;\r
139         }\r
140     }\r
141 \r
142     protected boolean isAvailableLimitLoopCount() {\r
143         if (!isFetchNarrowingEffective()) {\r
144             return false;\r
145         }\r
146         if (isLimitByCursorForcedly()) {\r
147             return true;\r
148         }\r
149         if (isFetchNarrowingLoopCountEffective()) {\r
150             return true;\r
151         }\r
152         return false;\r
153     }\r
154 \r
155     protected void checkSafetyResult(boolean hasNext) {\r
156         if (hasNext && getSafetyMaxResultSize() > 0 && _requestCounter > (getSafetyMaxResultSize() + 1)) {\r
157             String msg = "You have already been in Danger Zone!";\r
158             msg = msg + " Please confirm your query or data of table: safetyMaxResultSize=" + getSafetyMaxResultSize();\r
159             throw new jp.sourceforge.ea2ddl.dao.allcommon.exception.DangerousResultSizeException(msg, getSafetyMaxResultSize());\r
160         }\r
161     }\r
162 \r
163     // ===================================================================================\r
164     //                                                                        Fetch Option\r
165     //                                                                        ============\r
166     protected boolean isFetchNarrowingEffective() {\r
167         return _fetchNarrowingBean.isFetchNarrowingEffective();\r
168     }\r
169 \r
170     protected boolean isFetchNarrowingSkipStartIndexEffective() {\r
171         return _fetchNarrowingBean.isFetchNarrowingSkipStartIndexEffective();\r
172     }\r
173 \r
174     protected boolean isFetchNarrowingLoopCountEffective() {\r
175         return _fetchNarrowingBean.isFetchNarrowingLoopCountEffective();\r
176     }\r
177 \r
178     protected int getFetchNarrowingSkipStartIndex() {\r
179         return _fetchNarrowingBean.getFetchNarrowingSkipStartIndex();\r
180     }\r
181 \r
182     protected int getFetchNarrowingLoopCount() {\r
183         return _fetchNarrowingBean.getFetchNarrowingLoopCount();\r
184     }\r
185 \r
186     public int getSafetyMaxResultSize() {\r
187         return _fetchNarrowingBean.getSafetyMaxResultSize();\r
188     }\r
189 \r
190     protected boolean isScrollableCursor() {\r
191         try {\r
192             return !(_resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY);\r
193         } catch (SQLException e) {\r
194             handleSQLException(e, null);\r
195             return false;// Unreachable!\r
196         }\r
197     }\r
198 \r
199     // ===================================================================================\r
200     //                                                                   Exception Handler\r
201     //                                                                   =================\r
202     protected void handleSQLException(SQLException e, Statement statement) {\r
203         new SQLExceptionHandler().handleSQLException(e, statement);\r
204     }\r
205     \r
206     // ===================================================================================\r
207     //                                                                            Accessor\r
208     //                                                                            ========\r
209     public boolean isOffsetByCursorForcedly() {\r
210         return _offsetByCursorForcedly;\r
211     }\r
212 \r
213     public boolean isLimitByCursorForcedly() {\r
214         return _limitByCursorForcedly;\r
215     }\r
216         \r
217         public boolean isSkipToCursorEnd() {\r
218             return _skipToCursorEnd;\r
219         }\r
220 }\r