• R/O
  • SSH

JdbcAcsess2: Commit

全てを再実装したJdbcAcsessです。


Commit MetaInfo

Revisionf27c15389a605704d5dc61da8d74f9f55b4a00f6 (tree)
Time2012-03-03 21:57:38
Authorshimakazuro
Commitershimakazuro

Log Message

mousewheelでfont変更

Change Summary

Incremental Difference

diff -r ab92438e0436 -r f27c15389a60 src/jdbcacsess2/main/JPanelSql.java
--- a/src/jdbcacsess2/main/JPanelSql.java Mon Feb 27 01:12:08 2012 +0900
+++ b/src/jdbcacsess2/main/JPanelSql.java Sat Mar 03 21:57:38 2012 +0900
@@ -615,6 +615,7 @@
615615 Font font = jTable.getFont();
616616 jTable.setFont(new Font(Font.MONOSPACED, font.getStyle(), font.getSize()));
617617
618+ new FontZoomByMouseWheel(jTable);
618619 resultsTableColumnFit = new TableColumnFit(jTable);
619620 jTable.setModel(new ResultsTableModel());
620621 }
diff -r ab92438e0436 -r f27c15389a60 src/jdbcacsess2/main/JmyTable.java
--- a/src/jdbcacsess2/main/JmyTable.java Mon Feb 27 01:12:08 2012 +0900
+++ b/src/jdbcacsess2/main/JmyTable.java Sat Mar 03 21:57:38 2012 +0900
@@ -1,15 +1,15 @@
11 /*
22 * Copyright 2011 Kazuhiro Shimada
33 *
4- * Licensed under the Apache License, Version 2.0 (the "License");
5- * you may not use this file except in compliance with the License.
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
77 *
8- * http://www.apache.org/licenses/LICENSE-2.0
8+ * http://www.apache.org/licenses/LICENSE-2.0
99 *
10- * Unless required by applicable law or agreed to in writing, software
10+ * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
12- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
@@ -40,9 +40,6 @@
4040
4141 private static final long serialVersionUID = -7507194043135028576L;
4242
43- /**
44- *
45- */
4643 public JmyTable() {
4744 super();
4845 initialize();
@@ -112,6 +109,7 @@
112109 setRowSelectionAllowed(true);
113110 setAutoCreateRowSorter(true);
114111 setEditable(false);
112+ new FontZoomByMouseWheel(this);
115113 }
116114
117115 @Override
@@ -172,7 +170,7 @@
172170 /**
173171 * 追加変更削除が行われた行を選択する。
174172 */
175- private TableModelListener tableModelListener = new TableModelListener() {
173+ private final TableModelListener tableModelListener = new TableModelListener() {
176174 @Override
177175 public void tableChanged(TableModelEvent event) {
178176
@@ -221,4 +219,5 @@
221219 }
222220 }
223221 };
222+
224223 }
diff -r ab92438e0436 -r f27c15389a60 src/jdbcacsess2/sqlService/DataBaseConnection.java
--- a/src/jdbcacsess2/sqlService/DataBaseConnection.java Mon Feb 27 01:12:08 2012 +0900
+++ b/src/jdbcacsess2/sqlService/DataBaseConnection.java Sat Mar 03 21:57:38 2012 +0900
@@ -39,7 +39,6 @@
3939 import java.util.Properties;
4040 import java.util.StringTokenizer;
4141 import java.util.concurrent.Callable;
42-import java.util.concurrent.CopyOnWriteArrayList;
4342 import java.util.concurrent.ExecutionException;
4443 import java.util.concurrent.ExecutorService;
4544 import java.util.concurrent.Executors;
@@ -47,6 +46,8 @@
4746 import java.util.concurrent.TimeoutException;
4847 import java.util.logging.Level;
4948
49+import javax.swing.event.EventListenerList;
50+
5051 import jdbcacsess2.main.Jdbcacsess2;
5152 import jdbcacsess2.sqlService.exception.DbConnectAlreadyException;
5253 import jdbcacsess2.sqlService.exception.DbConnectDriverLoadException;
@@ -82,18 +83,10 @@
8283 private String connectName;
8384
8485 /**
85- * Connection の open/close等のコネクション状態変更を通知するリスナーリスト リスナーの通知呼び出し中に、@
86- * {@link DataBaseConnection#removeConnectionlisteners(DataBaseConnectionListener)}
87- * が呼ばても良い様に {@link CopyOnWriteArrayList}を使用する。
86+ * Connection の open/close等のコネクション状態変更またはトランザクションの開始、AutoCommitの状態変更
87+ * を通知するリスナーリスト
8888 */
89- private final List<DataBaseConnectionListener> connectionListeners = new CopyOnWriteArrayList<DataBaseConnectionListener>();
90-
91- /**
92- * トランザクションの開始、AutoCommitの状態変更 を通知するリスナーリスト リスナーの通知呼び出し中に、@
93- * {@link DataBaseConnection#removeTransactionlisteners(DataBaseTransactionListener)}
94- * が呼ばても良い様に {@link CopyOnWriteArrayList}を使用する。
95- */
96- private final List<DataBaseTransactionListener> transactionListeners = new CopyOnWriteArrayList<DataBaseTransactionListener>();
89+ private final EventListenerList listeners = new EventListenerList();
9790
9891 /**
9992 * connectionの使用中であるか
@@ -152,20 +145,14 @@
152145 * @param listener
153146 */
154147 public void addConnectionListener(DataBaseConnectionListener listener) {
155- if (listener == null) {
156- throw new NullPointerException();
157- }
158- connectionListeners.add(listener);
148+ listeners.add(DataBaseConnectionListener.class, listener);
159149 }
160150
161151 /**
162152 * 接続開始・終了リスナーの解除
163153 */
164154 public void removeConnectionlisteners(DataBaseConnectionListener listener) {
165- if (listener == null) {
166- throw new NullPointerException();
167- }
168- connectionListeners.remove(listener);
155+ listeners.remove(DataBaseConnectionListener.class, listener);
169156 }
170157
171158 /**
@@ -174,20 +161,14 @@
174161 * @param listener
175162 */
176163 public void addTransactionListener(DataBaseTransactionListener listener) {
177- if (listener == null) {
178- throw new NullPointerException();
179- }
180- transactionListeners.add(listener);
164+ listeners.add(DataBaseTransactionListener.class, listener);
181165 }
182166
183167 /**
184168 * トランザクション終了リスナーの解除
185169 */
186170 public void removeTransactionlisteners(DataBaseTransactionListener listener) {
187- if (listener == null) {
188- throw new NullPointerException();
189- }
190- transactionListeners.remove(listener);
171+ listeners.remove(DataBaseTransactionListener.class, listener);
191172 }
192173
193174 /**
@@ -303,7 +284,7 @@
303284
304285 executorService = Executors.newSingleThreadExecutor();
305286
306- for (DataBaseConnectionListener listener : connectionListeners) {
287+ for (DataBaseConnectionListener listener : listeners.getListeners(DataBaseConnectionListener.class)) {
307288 Jdbcacsess2.logger.fine("***opened***" + " " + listener.toString());
308289 listener.dataBaseConnectionOpened(this);
309290 }
@@ -352,7 +333,7 @@
352333 * SQL実行中の場合
353334 */
354335 public void close() throws DbConnectIllgalStateException {
355- for (DataBaseConnectionListener listener : connectionListeners) {
336+ for (DataBaseConnectionListener listener : listeners.getListeners(DataBaseConnectionListener.class)) {
356337 Jdbcacsess2.logger.fine("***closing***" + " " + listener.toString());
357338 listener.dataBaseConnectionClosing(this);
358339 }
@@ -376,7 +357,7 @@
376357 }).get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
377358
378359 // CLOSEが成功したときだけ通知する。
379- for (DataBaseConnectionListener listener : connectionListeners) {
360+ for (DataBaseConnectionListener listener : listeners.getListeners(DataBaseConnectionListener.class)) {
380361 Jdbcacsess2.logger.fine("***closed***" + " " + listener.toString());
381362 listener.dataBaseConnectionClosed(this);
382363 }
@@ -435,7 +416,7 @@
435416 }).get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
436417
437418 // 成功したときだけ通知する。
438- for (DataBaseTransactionListener listener : transactionListeners) {
419+ for (DataBaseTransactionListener listener : listeners.getListeners(DataBaseTransactionListener.class)) {
439420 listener.commitEnd(this);
440421 }
441422
@@ -462,7 +443,7 @@
462443 }).get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
463444
464445 // 成功したときだけ通知する。
465- for (DataBaseTransactionListener listener : transactionListeners) {
446+ for (DataBaseTransactionListener listener : listeners.getListeners(DataBaseTransactionListener.class)) {
466447 listener.rollbackEnd(this);
467448 }
468449
@@ -504,7 +485,7 @@
504485 }).get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
505486
506487 // 成功したときだけ通知する。
507- for (DataBaseTransactionListener listener : transactionListeners) {
488+ for (DataBaseTransactionListener listener : listeners.getListeners(DataBaseTransactionListener.class)) {
508489 listener.autoCommitChange(this, autoCommit);
509490 }
510491
diff -r ab92438e0436 -r f27c15389a60 src/jdbcacsess2/sqlService/DataBaseListener.java
--- a/src/jdbcacsess2/sqlService/DataBaseListener.java Mon Feb 27 01:12:08 2012 +0900
+++ b/src/jdbcacsess2/sqlService/DataBaseListener.java Sat Mar 03 21:57:38 2012 +0900
@@ -1,27 +1,29 @@
11 /*
22 * Copyright 2011 Kazuhiro Shimada
33 *
4- * Licensed under the Apache License, Version 2.0 (the "License");
5- * you may not use this file except in compliance with the License.
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
77 *
8- * http://www.apache.org/licenses/LICENSE-2.0
8+ * http://www.apache.org/licenses/LICENSE-2.0
99 *
10- * Unless required by applicable law or agreed to in writing, software
10+ * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
12- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
1616 package jdbcacsess2.sqlService;
1717
18+import java.util.EventListener;
19+
1820 /**
1921 * DataBaseConnectionに関するリスナーのマーカクラス
2022 *
2123 * @author sima
2224 *
2325 */
24-public interface DataBaseListener {
26+public interface DataBaseListener extends EventListener {
2527
2628
2729 }
diff -r ab92438e0436 -r f27c15389a60 src/jdbcacsess2/sqlService/SqlAsyncExecute.java
--- a/src/jdbcacsess2/sqlService/SqlAsyncExecute.java Mon Feb 27 01:12:08 2012 +0900
+++ b/src/jdbcacsess2/sqlService/SqlAsyncExecute.java Sat Mar 03 21:57:38 2012 +0900
@@ -19,7 +19,6 @@
1919 import java.sql.ResultSet;
2020 import java.sql.SQLException;
2121 import java.util.ArrayList;
22-import java.util.Collections;
2322 import java.util.List;
2423 import java.util.concurrent.Callable;
2524 import java.util.concurrent.ExecutionException;
@@ -28,6 +27,8 @@
2827 import java.util.concurrent.TimeoutException;
2928 import java.util.logging.Level;
3029
30+import javax.swing.event.EventListenerList;
31+
3132 import jdbcacsess2.main.Jdbcacsess2;
3233 import jdbcacsess2.main.ShowDialog;
3334 import jdbcacsess2.sqlService.SqlExecuteParmeter.Parameter;
@@ -55,7 +56,7 @@
5556 /**
5657 * 処理結果通知リスナーのリスト
5758 */
58- private final List<SqlExecutedListener> sqlExecutedListeners;
59+ private final EventListenerList sqlExecutedListeners;
5960 /**
6061 * 実行中のスレッド
6162 */
@@ -70,7 +71,7 @@
7071 */
7172 public SqlAsyncExecute(String sqlSentence, String sentenceSeparator) {
7273
73- sqlExecutedListeners = Collections.synchronizedList(new ArrayList<SqlExecutedListener>());
74+ sqlExecutedListeners = new EventListenerList();
7475
7576 sqlExecuteSentenceList = new SqlExecuteSentencies(sqlSentence, sentenceSeparator).getSqlExecuteSentenceList();
7677 }
@@ -127,27 +128,14 @@
127128 * @param listener
128129 */
129130 public void addSqlExcutedListener(SqlExecutedListener listener) {
130- if (listener == null) {
131- throw new NullPointerException();
132- }
133- sqlExecutedListeners.add(listener);
131+ sqlExecutedListeners.add(SqlExecutedListener.class, listener);
134132 }
135133
136134 /**
137135 * 結果受け取りリスナーの削除
138136 */
139137 public void removeSqlExcutedListener(SqlExecutedListener listener) {
140- if (listener == null) {
141- throw new NullPointerException();
142- }
143- sqlExecutedListeners.remove(listener);
144- }
145-
146- /**
147- * 結果受け取りリスナーの全削除
148- */
149- public void removeAllSqlExcutedListener() {
150- sqlExecutedListeners.clear();
138+ sqlExecutedListeners.remove(SqlExecutedListener.class, listener);
151139 }
152140
153141 /**
@@ -170,7 +158,7 @@
170158 SqlTask sqlTask = new SqlTask(dataBaseConnection);
171159 thread = new Thread(sqlTask);
172160 thread.start();
173- for (SqlExecutedListener l : sqlExecutedListeners) {
161+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
174162 l.taskAccept(sqlTask);
175163 }
176164 Jdbcacsess2.logger.fine("(execute) return.");
@@ -238,287 +226,287 @@
238226 /**
239227 * コンストラクタ。
240228 */
241- public SqlTask(DataBaseConnection dataBaseConnection) {
242- this.dataBaseConnection = dataBaseConnection;
243- }
244-
245- /**
246- * スレッド実行メソッド
247- */
248- public void run() {
249- Jdbcacsess2.logger.info("(task)beging.");
250-
251- // コネクションクローズ時に、スレッドの後始末を自動的に行う為、リスナー登録
252- dataBaseConnection.addConnectionListener(changeConnection);
253-
254- for (SqlExecuteSentence sentence : sqlExecuteSentenceList) {
255- if (Thread.interrupted()) {
256- Jdbcacsess2.logger.info(" (task)canceled.");
257- break;
258- }
259- sqlExec(sentence);
260- }
261-
262- // 全てのSQLが終了した時にロックを開放する
263- try {
264- dataBaseConnection.unlockConnection();
265- } catch (DbConnectIllgalStateException e) {
266- // ありえない例外
267- e.printStackTrace();
268- throw new RuntimeException(e);
269- }
270-
271- // 後始末リスナーの削除
272- dataBaseConnection.removeConnectionlisteners(changeConnection);
273-
274- for (SqlExecutedListener l : sqlExecutedListeners) {
275- l.executeAllEnd();
276- }
277- }
278-
279- private void sqlExec(SqlExecuteSentence sqlExecuteSentence) {
280- sqlTaskThrow = null;
281- timeMillisThreadStart = System.currentTimeMillis();
282- timeMillisThreadEnd = 0;
283- rowCnt = 0;
284- try {
285- Jdbcacsess2.logger.info(" (Statement)EXECSQL=[" + sqlExecuteSentence.getSqlSentence() + "]");
286- for (SqlExecutedListener l : sqlExecutedListeners) {
287- l.executBegin(sqlExecuteSentence);
288- }
289-
290- if (sqlExecuteSentence.getSqlCommand().equals("CALL")) {
291- preparedStatement = dataBaseConnection.prepareCall(sqlExecuteSentence.getSqlSentence());
292- } else {
293- preparedStatement = dataBaseConnection.prepareStatement(sqlExecuteSentence.getSqlSentence());
294- }
295-
296- // パラメータ取り込み処理がfalseを返すまで繰り返す
297- SqlInputParameter sqlInputParameter = sqlExecuteSentence.getSqlInputParameter();
298-
299- while (sqlInputParameter.getSqlExecuteParmeter().hasNext()) {
300- if (Thread.interrupted()) {
301- Jdbcacsess2.logger.info(" (task)canceled.");
302- break;
303- }
304-
305- // パラメータ設定を呼び出す
306- Parameter parameter = sqlInputParameter.getSqlExecuteParmeter().getParameter();
307-
308- // preparedStatementのパラメータ設定
309- setParameters(sqlInputParameter.getInputItemNames(), parameter);
310-
311- // SQL実行し、結果により受け取る方法を振り分ける
312- if (preparedStatement.execute()) {
313- readResultSet();
314- } else {
315- rowCnt += preparedStatement.getUpdateCount();
316- }
317-
318- }
319-
320- } catch (Throwable t) {
321- t.printStackTrace();
322- sqlTaskThrow = t;
323- } finally {
324- try {
325- if (preparedStatement != null) {
326- preparedStatement.close();
327- Jdbcacsess2.logger.info(" (task)Statement closed");
328- }
329- } catch (SQLException e) {
330- Jdbcacsess2.logger.log(Level.WARNING, "WARNING", e);
331- } finally {
332- preparedStatement = null;
333-
334- timeMillisThreadEnd = System.currentTimeMillis();
335-
336- if (sqlTaskThrow == null) {
337- for (SqlExecutedListener l : sqlExecutedListeners) {
338- l.executNormalFinish(rowCnt);
339- }
340- Jdbcacsess2.logger.info(" (task)noramal end. cnt=[" + rowCnt + "] "
341- + (timeMillisThreadEnd - timeMillisThreadStart) + "ms");
342- } else {
343- for (SqlExecutedListener l : sqlExecutedListeners) {
344- l.executeException(sqlTaskThrow);
345- }
346- Jdbcacsess2.logger.info(" (task)abnormal end. cnt=[" + rowCnt + "] "
347- + (timeMillisThreadEnd - timeMillisThreadStart) + "ms");
348- }
349-
350- }
351- }
352- }
353-
354- /**
355- * JDBCprepareステートメントのパラメータを設定する。
356- *
357- * @param sqlInputItems
358- * パラメータ名称リスト
359- * @param p
360- * KEY=パラメータリストのインデックス/VALUE=SQL型 のマップ。
361- */
362- private void setParameters(ArrayList<String> sqlInputItems, Parameter p)
363- throws SQLException {
364-
365- Jdbcacsess2.logger.fine(" (setParameters)VALUES=" + p.values + "SQLTYPES=" + p.sqlTypes + "");
366-
367- if (sqlInputItems.size() != p.values.size()) {
368- throw new IllegalArgumentException("入力パラ数が分析結果と不一致:" + "Input=" + p.values.size() + " analized="
369- + sqlInputItems);
370- }
371-
372- for (int i = 0; i < p.values.size(); i++) {
373- Object o = p.values.get(i);
374- ConstSqlTypes constSqlTypes = p.sqlTypes.get(i);
229+ public SqlTask(DataBaseConnection dataBaseConnection) {
230+ this.dataBaseConnection = dataBaseConnection;
231+ }
375232
376- if (constSqlTypes == null) {
377- preparedStatement.setObject(i + 1, o);
378- } else {
379- preparedStatement.setObject(i + 1, o, constSqlTypes.getValue());
380- Jdbcacsess2.logger.fine(" (setParameters)" + constSqlTypes);
381- }
382- }
383- }
384-
385- /**
386- * 検索結果を取り出す
387- *
388- * @throws Throwable
389- */
390- private void readResultSet() throws Throwable {
391-
392- ResultSet resultSet = preparedStatement.getResultSet();
393- // getMetaData()は、getResultSet()を実行してから行う。
394- // sqliteは、"IllegalStateException: SQLite JDBC: inconsistent internal state"
395- // 例外が発生する。
396- List<ColumnAttributeResult> list = ColumnAttributeResult.convColumnAttributeResult(resultSet.getMetaData());
397-
398- Jdbcacsess2.logger.info(" (task)resultSet opened.");
399- for (SqlExecutedListener l : sqlExecutedListeners) {
400- l.resultHeader(list);
401- }
402-
403- int columnCnt = list.size();
404-
405- try {
406- while (resultSet.next()) {
407- synchronized (this) {
408- if (Thread.interrupted()) {
409- Jdbcacsess2.logger.info(" (task)canceled.");
410- break;
411- }
412- ArrayList<Object> results = new ArrayList<Object>(columnCnt);
413- for (int i = 1; i <= columnCnt; i++) {
414- results.add(resultSet.getObject(i));
415- }
416-
417- rowCnt++;
418- for (SqlExecutedListener l : sqlExecutedListeners) {
419- l.resultDetail(rowCnt, results);
420- }
421- Jdbcacsess2.logger.finest(" (task)results notified.");
422-
423- if (rowCnt % resultRowLimitCnt == 0) {
424-
425- available = true;
426- new Thread() {
427- @Override
428- public void run() {
429- for (SqlExecutedListener l : sqlExecutedListeners) {
430- l.statusContinue(rowCnt);
431- }
432- }
433- }.start();
434- Jdbcacsess2.logger.info(" (task)waiting.");
233+ /**
234+ * スレッド実行メソッド
235+ */
236+ public void run() {
237+ Jdbcacsess2.logger.info("(task)beging.");
435238
436- while (available) {
437- try {
438- wait();
439- } catch (InterruptedException e) {
440- Jdbcacsess2.logger.fine(" (task)interrupted.");
441- // wait() により割り込みフラグがクリアされたので、
442- // 自身にもう一度割り込みをかける。ループ脱出をを検知させる為。
443- Thread.currentThread().interrupt();
444- break;
445- }
446- }
447- Jdbcacsess2.logger.info(" (task)wake up.");
448- }
449- }
450- }
451- } catch (Throwable t) {
452- throw t;
453- } finally {
454- resultSet.close();
455- Jdbcacsess2.logger.info(" (task)resultSet closed.");
456- }
457- }
458-
459- /**
460- * 待機中のSQL実行スレッドを再開する
461- */
462- @Override
463- public void taskWakeUp() {
464- synchronized (this) {
465- available = false;
466- notifyAll();
467- }
468- }
469-
470- /**
471- * 実行中のSQL実行スレッドを中止を要求する
472- */
473- @Override
474- public void taskCancel() {
475- thread.interrupt();
476- }
239+ // コネクションクローズ時に、スレッドの後始末を自動的に行う為、リスナー登録
240+ dataBaseConnection.addConnectionListener(changeConnection);
477241
478- /**
479- * SQL実行スレッドの終了を待ち合わせる
480- */
481- @Override
482- public void taskJoin(int timeoutSeconds) {
483- Jdbcacsess2.logger.info(" (join)joining...");
484- try {
485- Executors.newSingleThreadExecutor().submit(new Callable<Object>() {
486- @Override
487- public Object call() throws Exception {
488- thread.join();
489- return null;
490- }
491- }).get(timeoutSeconds, TimeUnit.SECONDS);
492- } catch (InterruptedException e) {
493- Jdbcacsess2.logger.log(Level.WARNING, "WARNING", e);
494- } catch (ExecutionException e) {
495- e.printStackTrace();
496- } catch (TimeoutException e) {
497- ShowDialog.errorMessage(e);
498- }
499- Jdbcacsess2.logger.info(" (join)joined.");
500- }
242+ for (SqlExecuteSentence sentence : sqlExecuteSentenceList) {
243+ if (Thread.interrupted()) {
244+ Jdbcacsess2.logger.info(" (task)canceled.");
245+ break;
246+ }
247+ sqlExec(sentence);
248+ }
501249
502- /**
503- *
504- * @return 処理時間 単位はミリ秒
505- */
506- @Override
507- public long getExecutionTime() {
508- if (timeMillisThreadStart == 0) {
509- return 0;
510- }
511- if (timeMillisThreadEnd == 0) {
512- return 0;
513- }
514- return timeMillisThreadEnd - timeMillisThreadStart;
515- }
250+ // 全てのSQLが終了した時にロックを開放する
251+ try {
252+ dataBaseConnection.unlockConnection();
253+ } catch (DbConnectIllgalStateException e) {
254+ // ありえない例外
255+ e.printStackTrace();
256+ throw new RuntimeException(e);
257+ }
516258
517- @Override
518- public int getCnt() {
519- return sqlExecuteSentenceList.size();
259+ // 後始末リスナーの削除
260+ dataBaseConnection.removeConnectionlisteners(changeConnection);
520261
521- }
262+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
263+ l.executeAllEnd();
264+ }
265+ }
266+
267+ private void sqlExec(SqlExecuteSentence sqlExecuteSentence) {
268+ sqlTaskThrow = null;
269+ timeMillisThreadStart = System.currentTimeMillis();
270+ timeMillisThreadEnd = 0;
271+ rowCnt = 0;
272+ try {
273+ Jdbcacsess2.logger.info(" (Statement)EXECSQL=[" + sqlExecuteSentence.getSqlSentence() + "]");
274+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
275+ l.executBegin(sqlExecuteSentence);
276+ }
277+
278+ if (sqlExecuteSentence.getSqlCommand().equals("CALL")) {
279+ preparedStatement = dataBaseConnection.prepareCall(sqlExecuteSentence.getSqlSentence());
280+ } else {
281+ preparedStatement = dataBaseConnection.prepareStatement(sqlExecuteSentence.getSqlSentence());
282+ }
283+
284+ // パラメータ取り込み処理がfalseを返すまで繰り返す
285+ SqlInputParameter sqlInputParameter = sqlExecuteSentence.getSqlInputParameter();
286+
287+ while (sqlInputParameter.getSqlExecuteParmeter().hasNext()) {
288+ if (Thread.interrupted()) {
289+ Jdbcacsess2.logger.info(" (task)canceled.");
290+ break;
291+ }
292+
293+ // パラメータ設定を呼び出す
294+ Parameter parameter = sqlInputParameter.getSqlExecuteParmeter().getParameter();
295+
296+ // preparedStatementのパラメータ設定
297+ setParameters(sqlInputParameter.getInputItemNames(), parameter);
298+
299+ // SQL実行し、結果により受け取る方法を振り分ける
300+ if (preparedStatement.execute()) {
301+ readResultSet();
302+ } else {
303+ rowCnt += preparedStatement.getUpdateCount();
304+ }
305+
306+ }
307+
308+ } catch (Throwable t) {
309+ t.printStackTrace();
310+ sqlTaskThrow = t;
311+ } finally {
312+ try {
313+ if (preparedStatement != null) {
314+ preparedStatement.close();
315+ Jdbcacsess2.logger.info(" (task)Statement closed");
316+ }
317+ } catch (SQLException e) {
318+ Jdbcacsess2.logger.log(Level.WARNING, "WARNING", e);
319+ } finally {
320+ preparedStatement = null;
321+
322+ timeMillisThreadEnd = System.currentTimeMillis();
323+
324+ if (sqlTaskThrow == null) {
325+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
326+ l.executNormalFinish(rowCnt);
327+ }
328+ Jdbcacsess2.logger.info(" (task)noramal end. cnt=[" + rowCnt + "] "
329+ + (timeMillisThreadEnd - timeMillisThreadStart) + "ms");
330+ } else {
331+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
332+ l.executeException(sqlTaskThrow);
333+ }
334+ Jdbcacsess2.logger.info(" (task)abnormal end. cnt=[" + rowCnt + "] "
335+ + (timeMillisThreadEnd - timeMillisThreadStart) + "ms");
336+ }
337+
338+ }
339+ }
340+ }
341+
342+ /**
343+ * JDBCprepareステートメントのパラメータを設定する。
344+ *
345+ * @param sqlInputItems
346+ * パラメータ名称リスト
347+ * @param p
348+ * KEY=パラメータリストのインデックス/VALUE=SQL型 のマップ。
349+ */
350+ private void setParameters(ArrayList<String> sqlInputItems, Parameter p)
351+ throws SQLException {
352+
353+ Jdbcacsess2.logger.fine(" (setParameters)VALUES=" + p.values + "SQLTYPES=" + p.sqlTypes + "");
354+
355+ if (sqlInputItems.size() != p.values.size()) {
356+ throw new IllegalArgumentException("入力パラ数が分析結果と不一致:" + "Input=" + p.values.size() + " analized="
357+ + sqlInputItems);
358+ }
359+
360+ for (int i = 0; i < p.values.size(); i++) {
361+ Object o = p.values.get(i);
362+ ConstSqlTypes constSqlTypes = p.sqlTypes.get(i);
363+
364+ if (constSqlTypes == null) {
365+ preparedStatement.setObject(i + 1, o);
366+ } else {
367+ preparedStatement.setObject(i + 1, o, constSqlTypes.getValue());
368+ Jdbcacsess2.logger.fine(" (setParameters)" + constSqlTypes);
369+ }
370+ }
371+ }
372+
373+ /**
374+ * 検索結果を取り出す
375+ *
376+ * @throws Throwable
377+ */
378+ private void readResultSet() throws Throwable {
379+
380+ ResultSet resultSet = preparedStatement.getResultSet();
381+ // getMetaData()は、getResultSet()を実行してから行う。
382+ // sqliteは、"IllegalStateException: SQLite JDBC: inconsistent internal state"
383+ // 例外が発生する。
384+ List<ColumnAttributeResult> list = ColumnAttributeResult.convColumnAttributeResult(resultSet.getMetaData());
385+
386+ Jdbcacsess2.logger.info(" (task)resultSet opened.");
387+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
388+ l.resultHeader(list);
389+ }
390+
391+ int columnCnt = list.size();
392+
393+ try {
394+ while (resultSet.next()) {
395+ synchronized (this) {
396+ if (Thread.interrupted()) {
397+ Jdbcacsess2.logger.info(" (task)canceled.");
398+ break;
399+ }
400+ ArrayList<Object> results = new ArrayList<Object>(columnCnt);
401+ for (int i = 1; i <= columnCnt; i++) {
402+ results.add(resultSet.getObject(i));
403+ }
404+
405+ rowCnt++;
406+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
407+ l.resultDetail(rowCnt, results);
408+ }
409+ Jdbcacsess2.logger.finest(" (task)results notified.");
410+
411+ if (rowCnt % resultRowLimitCnt == 0) {
412+
413+ available = true;
414+ new Thread() {
415+ @Override
416+ public void run() {
417+ for (SqlExecutedListener l : sqlExecutedListeners.getListeners(SqlExecutedListener.class)) {
418+ l.statusContinue(rowCnt);
419+ }
420+ }
421+ }.start();
422+ Jdbcacsess2.logger.info(" (task)waiting.");
423+
424+ while (available) {
425+ try {
426+ wait();
427+ } catch (InterruptedException e) {
428+ Jdbcacsess2.logger.fine(" (task)interrupted.");
429+ // wait() により割り込みフラグがクリアされたので、
430+ // 自身にもう一度割り込みをかける。ループ脱出をを検知させる為。
431+ Thread.currentThread().interrupt();
432+ break;
433+ }
434+ }
435+ Jdbcacsess2.logger.info(" (task)wake up.");
436+ }
437+ }
438+ }
439+ } catch (Throwable t) {
440+ throw t;
441+ } finally {
442+ resultSet.close();
443+ Jdbcacsess2.logger.info(" (task)resultSet closed.");
444+ }
445+ }
446+
447+ /**
448+ * 待機中のSQL実行スレッドを再開する
449+ */
450+ @Override
451+ public void taskWakeUp() {
452+ synchronized (this) {
453+ available = false;
454+ notifyAll();
455+ }
456+ }
457+
458+ /**
459+ * 実行中のSQL実行スレッドを中止を要求する
460+ */
461+ @Override
462+ public void taskCancel() {
463+ thread.interrupt();
464+ }
465+
466+ /**
467+ * SQL実行スレッドの終了を待ち合わせる
468+ */
469+ @Override
470+ public void taskJoin(int timeoutSeconds) {
471+ Jdbcacsess2.logger.info(" (join)joining...");
472+ try {
473+ Executors.newSingleThreadExecutor().submit(new Callable<Object>() {
474+ @Override
475+ public Object call() throws Exception {
476+ thread.join();
477+ return null;
478+ }
479+ }).get(timeoutSeconds, TimeUnit.SECONDS);
480+ } catch (InterruptedException e) {
481+ Jdbcacsess2.logger.log(Level.WARNING, "WARNING", e);
482+ } catch (ExecutionException e) {
483+ e.printStackTrace();
484+ } catch (TimeoutException e) {
485+ ShowDialog.errorMessage(e);
486+ }
487+ Jdbcacsess2.logger.info(" (join)joined.");
488+ }
489+
490+ /**
491+ *
492+ * @return 処理時間 単位はミリ秒
493+ */
494+ @Override
495+ public long getExecutionTime() {
496+ if (timeMillisThreadStart == 0) {
497+ return 0;
498+ }
499+ if (timeMillisThreadEnd == 0) {
500+ return 0;
501+ }
502+ return timeMillisThreadEnd - timeMillisThreadStart;
503+ }
504+
505+ @Override
506+ public int getCnt() {
507+ return sqlExecuteSentenceList.size();
508+
509+ }
522510 }// class SqlTask end
523511
524512
diff -r ab92438e0436 -r f27c15389a60 src/jdbcacsess2/sqlService/SqlExecutedListener.java
--- a/src/jdbcacsess2/sqlService/SqlExecutedListener.java Mon Feb 27 01:12:08 2012 +0900
+++ b/src/jdbcacsess2/sqlService/SqlExecutedListener.java Sat Mar 03 21:57:38 2012 +0900
@@ -1,20 +1,21 @@
11 /*
22 * Copyright 2011 Kazuhiro Shimada
33 *
4- * Licensed under the Apache License, Version 2.0 (the "License");
5- * you may not use this file except in compliance with the License.
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
77 *
8- * http://www.apache.org/licenses/LICENSE-2.0
8+ * http://www.apache.org/licenses/LICENSE-2.0
99 *
10- * Unless required by applicable law or agreed to in writing, software
10+ * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
12- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
1616 package jdbcacsess2.sqlService;
1717
18+import java.util.EventListener;
1819 import java.util.List;
1920
2021 import jdbcacsess2.sqlService.parse.SqlExecuteSentencies.SqlExecuteSentence;
@@ -25,7 +26,7 @@
2526 * @author sima
2627 *
2728 */
28-public interface SqlExecutedListener {
29+public interface SqlExecutedListener extends EventListener {
2930
3031 /**
3132 * SQL実行が受け付けた時に呼ばれます。このイベントだけは、呼出と同じスレッドで呼ばれ、SQL実行スレッドからではありません。
Show on old repository browser