全てを再実装したJdbcAcsessです。
Revision | 9784314ce47af585b75269e3f389bff4acc6059d (tree) |
---|---|
Time | 2012-02-14 21:26:34 |
Author | shimakazuro |
Commiter | shimakazuro |
パッケージとクラスの整理
@@ -48,7 +48,7 @@ | ||
48 | 48 | import jdbcacsess2.sqlService.DataBaseTransactionListener; |
49 | 49 | import jdbcacsess2.sqlService.PropertyResultSetTableModel; |
50 | 50 | import jdbcacsess2.sqlService.ResultsTableModel; |
51 | -import jdbcacsess2.sqlService.SqlExecuteSentencies.SqlExecuteSentence; | |
51 | +import jdbcacsess2.sqlService.parse.SqlExecuteSentencies.SqlExecuteSentence; | |
52 | 52 | import jdbcacsess2.sqlService.SqlExecuteTask; |
53 | 53 | import jdbcacsess2.sqlService.SqlExecutedListener; |
54 | 54 |
@@ -63,8 +63,6 @@ | ||
63 | 63 | import jdbcacsess2.sqlService.DataBaseConnection; |
64 | 64 | import jdbcacsess2.sqlService.DataBaseConnectionListener; |
65 | 65 | import jdbcacsess2.sqlService.DataBaseTransactionListener; |
66 | -import jdbcacsess2.sqlService.PropertyDBObjectsTableModel; | |
67 | -import jdbcacsess2.sqlService.PropertyExportedKeyTableModel; | |
68 | 66 | import jdbcacsess2.sqlService.ReferenceColumnResult; |
69 | 67 | import jdbcacsess2.sqlService.SqlAsyncExecute; |
70 | 68 | import jdbcacsess2.sqlService.SqlExecutedListener; |
@@ -73,6 +71,8 @@ | ||
73 | 71 | import jdbcacsess2.sqlService.dbobject.DBObjectTables.DBObjectTable; |
74 | 72 | import jdbcacsess2.sqlService.dbobject.DBObjectsRoot; |
75 | 73 | import jdbcacsess2.sqlService.dbobject.DBobjectMutableTreeTableNode; |
74 | +import jdbcacsess2.sqlService.dbobject.PropertyDBObjectsTableModel; | |
75 | +import jdbcacsess2.sqlService.dbobject.PropertyExportedKeyTableModel; | |
76 | 76 | import jdbcacsess2.sqlService.exception.DbConnectAlreadyException; |
77 | 77 | import jdbcacsess2.sqlService.exception.DbConnectIllgalStateException; |
78 | 78 | import jdbcacsess2.sqlService.history.HistryTableModel; |
@@ -691,8 +691,7 @@ | ||
691 | 691 | // TABLE 系の時のみexportkey情報を表示する |
692 | 692 | JTable jTable = view.getCurrentJPanelSession().getJTableExportedKey(); |
693 | 693 | if (dbObject instanceof DBObjectTable) { |
694 | - List<ReferenceColumnResult> exportedKey = ((DBObjectTable) dbObject).getExportedKey(); | |
695 | - jTable.setModel(new PropertyExportedKeyTableModel(exportedKey)); | |
694 | + jTable.setModel(new PropertyExportedKeyTableModel(((DBObjectTable) dbObject).getExportedKey())); | |
696 | 695 | } else { |
697 | 696 | // TABLE系以外なので空のモデルを設定する |
698 | 697 | jTable.setModel(new DefaultTableModel()); |
@@ -1,66 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright 2011 Kazuhiro Shimada | |
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 | - | |
17 | -package jdbcacsess2.sqlService; | |
18 | - | |
19 | -import java.util.List; | |
20 | - | |
21 | -import javax.swing.table.AbstractTableModel; | |
22 | - | |
23 | -import jdbcacsess2.sqlService.dbobject.DBObject.Property; | |
24 | - | |
25 | -/** | |
26 | - * @author sima | |
27 | - * | |
28 | - */ | |
29 | -public class PropertyDBObjectsTableModel extends AbstractTableModel { | |
30 | - private static final long serialVersionUID = 3293479625219161204L; | |
31 | - | |
32 | - private List<Property> properties; | |
33 | - | |
34 | - public PropertyDBObjectsTableModel(List<Property> properties) { | |
35 | - this.properties = properties; | |
36 | - } | |
37 | - | |
38 | - @Override | |
39 | - public int getColumnCount() { | |
40 | - return 2; | |
41 | - } | |
42 | - | |
43 | - @Override | |
44 | - public int getRowCount() { | |
45 | - return properties.size(); | |
46 | - } | |
47 | - | |
48 | - @Override | |
49 | - public String getColumnName(int column) { | |
50 | - if (column == 0) { | |
51 | - return "name"; | |
52 | - } else { | |
53 | - return "value"; | |
54 | - } | |
55 | - } | |
56 | - | |
57 | - @Override | |
58 | - public Object getValueAt(int rowIndex, int columnIndex) { | |
59 | - if (columnIndex == 0) { | |
60 | - return properties.get(rowIndex).getName(); | |
61 | - } else { | |
62 | - return properties.get(rowIndex).getValue(); | |
63 | - } | |
64 | - } | |
65 | -} | |
66 | - |
@@ -1,125 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright 2011 Kazuhiro Shimada | |
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 | - | |
17 | -package jdbcacsess2.sqlService; | |
18 | - | |
19 | -import java.util.List; | |
20 | - | |
21 | -import javax.swing.table.AbstractTableModel; | |
22 | - | |
23 | -/** | |
24 | - * @author sima | |
25 | - * | |
26 | - */ | |
27 | -public class PropertyExportedKeyTableModel extends AbstractTableModel { | |
28 | - private static final long serialVersionUID = 6816351858372050538L; | |
29 | - private List<ReferenceColumnResult> exportKey; | |
30 | - | |
31 | - public PropertyExportedKeyTableModel(List<ReferenceColumnResult> exportKey) { | |
32 | - this.exportKey = exportKey; | |
33 | - } | |
34 | - | |
35 | - @Override | |
36 | - public int getColumnCount() { | |
37 | - return 14; | |
38 | - } | |
39 | - | |
40 | - @Override | |
41 | - public int getRowCount() { | |
42 | - return exportKey.size(); | |
43 | - } | |
44 | - | |
45 | - @Override | |
46 | - public String getColumnName(int column) { | |
47 | - switch (column) { | |
48 | - case 0: | |
49 | - return "PKcat"; | |
50 | - case 1: | |
51 | - return "PKschem"; | |
52 | - case 2: | |
53 | - return "PKtable"; | |
54 | - case 3: | |
55 | - return "PKname"; | |
56 | - case 4: | |
57 | - return "PKcolumn"; | |
58 | - | |
59 | - case 5: | |
60 | - return "FKcat"; | |
61 | - case 6: | |
62 | - return "FKschem"; | |
63 | - case 7: | |
64 | - return "FKtable"; | |
65 | - case 8: | |
66 | - return "FKname"; | |
67 | - case 9: | |
68 | - return "FKcolumn"; | |
69 | - | |
70 | - case 10: | |
71 | - return "KeySeq"; | |
72 | - | |
73 | - case 11: | |
74 | - return "UpdateRule"; | |
75 | - case 12: | |
76 | - return "DeleteRule"; | |
77 | - | |
78 | - case 13: | |
79 | - return "Deferrability"; | |
80 | - } | |
81 | - return ""; | |
82 | - } | |
83 | - | |
84 | - @Override | |
85 | - public Object getValueAt(int rowIndex, int columnIndex) { | |
86 | - ReferenceColumnResult r = exportKey.get(rowIndex); | |
87 | - | |
88 | - switch (columnIndex) { | |
89 | - case 0: | |
90 | - return r.getPktableCat(); | |
91 | - case 1: | |
92 | - return r.getPktableSchem(); | |
93 | - case 2: | |
94 | - return r.getPktableName(); | |
95 | - case 3: | |
96 | - return r.getPkName(); | |
97 | - case 4: | |
98 | - return r.getPkcolumnName(); | |
99 | - | |
100 | - case 5: | |
101 | - return r.getFktableCat(); | |
102 | - case 6: | |
103 | - return r.getFktableSchem(); | |
104 | - case 7: | |
105 | - return r.getFktableName(); | |
106 | - case 8: | |
107 | - return r.getFkName(); | |
108 | - case 9: | |
109 | - return r.getFkcolumnName(); | |
110 | - | |
111 | - case 10: | |
112 | - return r.getKeySeq(); | |
113 | - | |
114 | - case 11: | |
115 | - return r.getUpdateRuleName(); | |
116 | - case 12: | |
117 | - return r.getDeleteRuleName(); | |
118 | - | |
119 | - case 13: | |
120 | - return r.getDeferrabilityName(); | |
121 | - } | |
122 | - return null; | |
123 | - } | |
124 | - | |
125 | -} |
@@ -25,7 +25,7 @@ | ||
25 | 25 | import javax.swing.table.AbstractTableModel; |
26 | 26 | |
27 | 27 | import jdbcacsess2.main.Jdbcacsess2; |
28 | -import jdbcacsess2.sqlService.SqlExecuteSentencies.SqlExecuteSentence; | |
28 | +import jdbcacsess2.sqlService.parse.SqlExecuteSentencies.SqlExecuteSentence; | |
29 | 29 | |
30 | 30 | /** |
31 | 31 | * @author sima |
@@ -31,8 +31,9 @@ | ||
31 | 31 | import jdbcacsess2.main.Jdbcacsess2; |
32 | 32 | import jdbcacsess2.main.ShowDialog; |
33 | 33 | import jdbcacsess2.sqlService.SqlExecuteParmeter.Parameter; |
34 | -import jdbcacsess2.sqlService.SqlExecuteSentencies.SqlExecuteSentence; | |
35 | 34 | import jdbcacsess2.sqlService.exception.DbConnectIllgalStateException; |
35 | +import jdbcacsess2.sqlService.parse.SqlExecuteSentencies; | |
36 | +import jdbcacsess2.sqlService.parse.SqlExecuteSentencies.SqlExecuteSentence; | |
36 | 37 | |
37 | 38 | /** |
38 | 39 | * SQL文を実行し、リスナーを通して処理結果を通知します。 |
@@ -1,243 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService; | |
17 | - | |
18 | -import java.util.ArrayList; | |
19 | -import java.util.regex.Pattern; | |
20 | - | |
21 | -import jdbcacsess2.main.Jdbcacsess2; | |
22 | - | |
23 | -/** | |
24 | - * SQL文を解析し、最初の命令句/入力変数/更新可能SELECT文であるか?などを抽出します。 | |
25 | - * | |
26 | - * 画面から入力されたSQLが複数文であった場合、1SQL文毎に分解されます。 SQL文の区切りは{@link SqlSentenceParse} | |
27 | - * で行われるので、通知されたSQL文の番号を使用して、それぞれのSQL文を区別します。 | |
28 | - * | |
29 | - * @author sima | |
30 | - * | |
31 | - */ | |
32 | -public class SqlExecuteSentencies { | |
33 | - | |
34 | - /** | |
35 | - * コンストラクタ、SQL文のparseを行う。 | |
36 | - * | |
37 | - * @param sqlSentence | |
38 | - * 分析したいSQL文 | |
39 | - * @param sentenceSeparator | |
40 | - * 複数SQL文を区切り正規表現文字列 | |
41 | - */ | |
42 | - public SqlExecuteSentencies(String sqlSentence, String sentenceSeparator) { | |
43 | - | |
44 | - | |
45 | - final SqlSentenceParse sqlSentenceParse = new SqlSentenceParse(); | |
46 | - | |
47 | - sqlSentenceParse.addSqlSentenceListener(new SqlExecuteSentence()); | |
48 | - | |
49 | - sqlSentenceParse.registSeparatePattern(Pattern.compile(sentenceSeparator)); | |
50 | - sqlSentenceParse.registSeparateListener(new SqlSentenceSparateListener() { | |
51 | - @Override | |
52 | - public void rangeSeparate(String matchKeyword, | |
53 | - int beginPosition, | |
54 | - int endPosition, | |
55 | - Pattern pattern) { | |
56 | - sqlSentenceParse.removeAllSqlSentenceListener(); | |
57 | - sqlSentenceParse.addSqlSentenceListener(new SqlExecuteSentence()); | |
58 | - } | |
59 | - }); | |
60 | - | |
61 | - // 解析開始 | |
62 | - sqlSentenceParse.parse(sqlSentence); | |
63 | - | |
64 | - Jdbcacsess2.logger.info(sqlExecuteSentenceList.toString()); | |
65 | - } | |
66 | - | |
67 | - private int seq = 0; | |
68 | - final private ArrayList<SqlExecuteSentence> sqlExecuteSentenceList = new ArrayList<SqlExecuteSentence>(); | |
69 | - | |
70 | - /** | |
71 | - * SQL文単位に分解された最終結果 | |
72 | - * | |
73 | - * @return SQL文解析結果のリスト | |
74 | - */ | |
75 | - public ArrayList<SqlExecuteSentence> getSqlExecuteSentenceList() { | |
76 | - return sqlExecuteSentenceList; | |
77 | - } | |
78 | - | |
79 | - /** | |
80 | - * 分解された1SQL文の解析結果 | |
81 | - * | |
82 | - * @author sima | |
83 | - * | |
84 | - */ | |
85 | - public class SqlExecuteSentence implements SqlSentenceListener { | |
86 | - | |
87 | - private String sqlSentence; | |
88 | - private int sentenceCount; | |
89 | - | |
90 | - /** | |
91 | - * SQLの連番 | |
92 | - * | |
93 | - * @return sentenceCount | |
94 | - */ | |
95 | - public int getSentenceCount() { | |
96 | - return sentenceCount; | |
97 | - } | |
98 | - | |
99 | - /** | |
100 | - * SQL文 | |
101 | - * | |
102 | - * @return sqlSentence | |
103 | - */ | |
104 | - public String getSqlSentence() { | |
105 | - return sqlSentence; | |
106 | - } | |
107 | - | |
108 | - private SqlInputParameter sqlInputParameter = new SqlInputParameter(); | |
109 | - | |
110 | - /** | |
111 | - * 入力パラメータ | |
112 | - * | |
113 | - * @return sqlInputParameter | |
114 | - */ | |
115 | - public SqlInputParameter getSqlInputParameter() { | |
116 | - return sqlInputParameter; | |
117 | - } | |
118 | - | |
119 | - private String sqlCommand; | |
120 | - | |
121 | - /** | |
122 | - * SQL文の最初の命令句 | |
123 | - * | |
124 | - * @return "SELECT","INSERT"."DELETE","CALL","CREATE","ALTER"等の文字列。 | |
125 | - * 常に大文字で返却されます 。 | |
126 | - */ | |
127 | - public String getSqlCommand() { | |
128 | - return sqlCommand; | |
129 | - } | |
130 | - | |
131 | - private boolean editable = false; | |
132 | - | |
133 | - /** | |
134 | - * 更新可能SELECT文であるか | |
135 | - * | |
136 | - * @return editable | |
137 | - */ | |
138 | - public boolean isEditable() { | |
139 | - return editable; | |
140 | - } | |
141 | - | |
142 | - private int phraseCnt = 0; | |
143 | - private boolean checkEnd = false; | |
144 | - private boolean select = false; | |
145 | - private boolean from = false; | |
146 | - | |
147 | - @Override | |
148 | - public void started(String sqlSentence) { | |
149 | - // finished で上書きされるの意味はない | |
150 | - this.sqlSentence = sqlSentence; | |
151 | - } | |
152 | - | |
153 | - @Override | |
154 | - public void rangeInput(String phrase, int begin, int end) { | |
155 | - sqlInputParameter.addInputItemName(phrase); | |
156 | - } | |
157 | - | |
158 | - @Override | |
159 | - public void rangePhrase(String phrase, int begin, int end) { | |
160 | - if (checkEnd) { | |
161 | - return; | |
162 | - } | |
163 | - String upperPhrase = phrase.toUpperCase(); | |
164 | - | |
165 | - phraseCnt++; | |
166 | - if (phraseCnt == 1 && upperPhrase.equals("SELECT")) { | |
167 | - select = true; | |
168 | - return; | |
169 | - } | |
170 | - if (!select) { | |
171 | - checkEnd = true; | |
172 | - editable = false; | |
173 | - return; | |
174 | - } | |
175 | - if (upperPhrase.equals("SELECT") || upperPhrase.equals("GROUP")) { | |
176 | - checkEnd = true; | |
177 | - editable = false; | |
178 | - return; | |
179 | - } | |
180 | - | |
181 | - if (upperPhrase.equals("FROM")) { | |
182 | - // FROM句を見つけたので、とりあえず更新可能とする | |
183 | - editable = true; | |
184 | - | |
185 | - from = true; | |
186 | - return; | |
187 | - } | |
188 | - if (upperPhrase.equals("WHERE")) { | |
189 | - from = false; | |
190 | - return; | |
191 | - } | |
192 | - | |
193 | - } | |
194 | - | |
195 | - @Override | |
196 | - public void rangeSymbol(String symbol, int begin, int end) { | |
197 | - if (checkEnd) { | |
198 | - return; | |
199 | - } | |
200 | - if (from && symbol.equals(",")) { | |
201 | - // FROM句中にカンマを見つけたので、更新不可が確定した | |
202 | - checkEnd = true; | |
203 | - editable = false; | |
204 | - return; | |
205 | - } | |
206 | - } | |
207 | - | |
208 | - @Override | |
209 | - public void finished(String sentence, String command) { | |
210 | - sqlSentence = sentence; | |
211 | - sqlCommand = command; | |
212 | - if (!sqlCommand.equals("")) { | |
213 | - sentenceCount = ++seq; | |
214 | - if (sqlCommand.equals("CREATE") || sqlCommand.equals("ALTER")) { | |
215 | - sqlInputParameter.clear(); | |
216 | - } | |
217 | - sqlExecuteSentenceList.add(this); | |
218 | - } | |
219 | - } | |
220 | - | |
221 | - @Override | |
222 | - public void rangeComment(String comment, int begin, int end) { | |
223 | - } | |
224 | - | |
225 | - @Override | |
226 | - public void rangeConstant(String constant, int begin, int end) { | |
227 | - } | |
228 | - | |
229 | - @Override | |
230 | - public void rangeDelimiter(String delimiter, int begin, int end) { | |
231 | - } | |
232 | - | |
233 | - @Override | |
234 | - public String toString() { | |
235 | - return "command:" + sqlCommand + " editable:" + editable + " inputItems:" | |
236 | - + sqlInputParameter.getInputItemNames() + "[" | |
237 | - + sqlSentence + "]"; | |
238 | - } | |
239 | - | |
240 | - } | |
241 | - | |
242 | - | |
243 | -} |
@@ -17,7 +17,7 @@ | ||
17 | 17 | |
18 | 18 | import java.util.List; |
19 | 19 | |
20 | -import jdbcacsess2.sqlService.SqlExecuteSentencies.SqlExecuteSentence; | |
20 | +import jdbcacsess2.sqlService.parse.SqlExecuteSentencies.SqlExecuteSentence; | |
21 | 21 | |
22 | 22 | /** |
23 | 23 | * SQL実行結果の通知するリスナーです。 |
@@ -1,150 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService; | |
17 | - | |
18 | -import java.util.ArrayList; | |
19 | -import java.util.HashMap; | |
20 | - | |
21 | -import jdbcacsess2.sqlService.SqlExecuteParmeter.Parameter; | |
22 | - | |
23 | -/** | |
24 | - * | |
25 | - * SQL文の入力パラメータに関する情報を、1つの実行SQL文分だけ集めたクラスです。 | |
26 | - * 1SQL文には複数のパラメータが想定されるので、それぞれの内容はArrayListでリスト化されています。 | |
27 | - * <ul> | |
28 | - * <li>SQL文中に記述された入力パラメータの名称:{@link SqlExecuteSentencies.SqlExecuteSentence} | |
29 | - * が解析した結果を格納する事を想定しています。 | |
30 | - * <li>入力パラメータの値とそのSQLTYPE:3パターンの使い方が出来ます。 | |
31 | - * <ol> | |
32 | - * <li>パラメータが無い | |
33 | - * <li>入力パラメータを指定しSQLを1回だけ実行する時 | |
34 | - * <li>1つのSQLで入力パラメータを切り替えながら順次実行する | |
35 | - * </ol> | |
36 | - * 3番目の使用方法は、PrepareしたSQL文に対して、入力パラメータの設定とexecuteが、複数回実行されるイメージです。 | |
37 | - * </ul> | |
38 | - * | |
39 | - * @author sima | |
40 | - * | |
41 | - */ | |
42 | -public class SqlInputParameter { | |
43 | - | |
44 | - private final Parameter parameter; | |
45 | - | |
46 | - public SqlInputParameter() { | |
47 | - parameter = new SqlExecuteParmeter.Parameter(); | |
48 | - parameter.values = new ArrayList<Object>(); | |
49 | - parameter.sqlTypes = new HashMap<Integer, ConstSqlTypes>(); | |
50 | - } | |
51 | - | |
52 | - /** | |
53 | - * 入力パラメータ名のSQL文字句要素 | |
54 | - */ | |
55 | - final private ArrayList<String> inputItemNames = new ArrayList<String>(); | |
56 | - | |
57 | - /** | |
58 | - * 入力パラメータ名のSQL文字句要素を返却します。このリストの順番に | |
59 | - * {@link SqlInputParameter#addParameter(Object, ConstSqlTypes)} | |
60 | - * でパラメータを設定する必要があります。 | |
61 | - * | |
62 | - * @return | |
63 | - */ | |
64 | - public ArrayList<String> getInputItemNames() { | |
65 | - return inputItemNames; | |
66 | - } | |
67 | - | |
68 | - /** | |
69 | - * 入力パラメータ名のSQL文字句要素を追加します。これは、{@link SqlExecuteSentencies}が結果格納する時に使用されます。 | |
70 | - * | |
71 | - * @param inputItemName | |
72 | - */ | |
73 | - void addInputItemName(String inputItemName) { | |
74 | - inputItemNames.add(inputItemName); | |
75 | - } | |
76 | - | |
77 | - /** | |
78 | - * パラメータの値とタイプをパラメータリストの最後に追加します。 | |
79 | - * | |
80 | - * @param value | |
81 | - * 値 | |
82 | - * @param constSqlType | |
83 | - * 値のSQLTYPE | |
84 | - */ | |
85 | - public void addParameter(Object value, ConstSqlTypes constSqlType) { | |
86 | - addParameter(parameter.values.size() - 1, value, constSqlType); | |
87 | - } | |
88 | - | |
89 | - /** | |
90 | - * パラメータの値とタイプをパラメータリストの順番を指定して追加します。 | |
91 | - * | |
92 | - * @param index | |
93 | - * {@link SqlInputParameter#inputItemNames}のリストに存在するindex | |
94 | - * @param value | |
95 | - * 値 | |
96 | - * @param constSqlType | |
97 | - * 値のSQLTYPE | |
98 | - */ | |
99 | - public void addParameter(Integer index, Object value, ConstSqlTypes constSqlType) { | |
100 | - inputItemNames.get(index); // check | |
101 | - | |
102 | - parameter.values.add(value); | |
103 | - parameter.sqlTypes.put(index, constSqlType); | |
104 | - } | |
105 | - | |
106 | - SqlExecuteParmeter getSqlExecuteParmeter() { | |
107 | - return sqlExecuteParmeter; | |
108 | - } | |
109 | - | |
110 | - /** | |
111 | - * デフォルトではパラメータ値は通常1SQLで1組となっています。<br> | |
112 | - * 同一SQLで複数組を処理したい場合、値とSQLTYPEを順次外部から与える方法を指定出来ます。 | |
113 | - * | |
114 | - * @param sqlExecuteParmeter | |
115 | - * {@link SqlExecuteParmeter}を実装した値とSQLTYPEの生成器。 | |
116 | - */ | |
117 | - public void setSqlExecuteParmeter(SqlExecuteParmeter sqlExecuteParmeter) { | |
118 | - this.sqlExecuteParmeter = sqlExecuteParmeter; | |
119 | - } | |
120 | - | |
121 | - private SqlExecuteParmeter sqlExecuteParmeter = new SqlExecuteParmeter() { | |
122 | - | |
123 | - boolean flg = true; | |
124 | - | |
125 | - @Override | |
126 | - public boolean hasNext() { | |
127 | - // 1回目の呼出はtrue、2回目以降はfalse | |
128 | - if (flg) { | |
129 | - flg = false; | |
130 | - return true; | |
131 | - } | |
132 | - return false; | |
133 | - } | |
134 | - | |
135 | - @Override | |
136 | - public Parameter getParameter() { | |
137 | - return parameter; | |
138 | - } | |
139 | - }; | |
140 | - | |
141 | - /** | |
142 | - * 入力パラメータ名とパラメータ値を全て初期化します。 | |
143 | - */ | |
144 | - public void clear() { | |
145 | - inputItemNames.clear(); | |
146 | - parameter.values.clear(); | |
147 | - parameter.sqlTypes.clear(); | |
148 | - } | |
149 | - | |
150 | -} |
@@ -1,117 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService; | |
17 | - | |
18 | - | |
19 | -/** | |
20 | - * SQL文を解析した結果の字句要素を通知するリスナーです。 | |
21 | - * | |
22 | - * @author sima | |
23 | - * | |
24 | - */ | |
25 | -public interface SqlSentenceListener { | |
26 | - | |
27 | - /** | |
28 | - * 処理開始 | |
29 | - * | |
30 | - * @param sqlSentence | |
31 | - * 解析対象のSQL文 | |
32 | - */ | |
33 | - public void started(String sqlSentence); | |
34 | - | |
35 | - /** | |
36 | - * コメント | |
37 | - * | |
38 | - * @param comment | |
39 | - * コメント文字列 | |
40 | - * @param beginPosition | |
41 | - * 開始位置 | |
42 | - * @param endPosition | |
43 | - * 終了位置 | |
44 | - */ | |
45 | - public void rangeComment(String comment, int beginPosition, int endPosition); | |
46 | - | |
47 | - /** | |
48 | - * SQL句と要素 | |
49 | - * | |
50 | - * @param phrase | |
51 | - * SQL句と要素文字列 | |
52 | - * @param beginPosition | |
53 | - * 開始位置 | |
54 | - * @param endPosition | |
55 | - * 終了位置 | |
56 | - */ | |
57 | - public void rangePhrase(String phrase, int beginPosition, int endPosition); | |
58 | - | |
59 | - /** | |
60 | - * SQL句と要素 | |
61 | - * | |
62 | - * @param input | |
63 | - * SQL句と要素文字列 | |
64 | - * @param beginPosition | |
65 | - * 開始位置 | |
66 | - * @param endPosition | |
67 | - * 終了位置 | |
68 | - */ | |
69 | - public void rangeInput(String input, int beginPosition, int endPosition); | |
70 | - | |
71 | - /** | |
72 | - * 定数 | |
73 | - * | |
74 | - * @param constant | |
75 | - * 定数 | |
76 | - * @param beginPosition | |
77 | - * 開始位置 | |
78 | - * @param endPosition | |
79 | - * 終了位置 | |
80 | - */ | |
81 | - public void rangeConstant(String constant, int beginPosition, int endPosition); | |
82 | - | |
83 | - /** | |
84 | - * デリミタ | |
85 | - * | |
86 | - * @param delimiter | |
87 | - * デリミタ文字列 | |
88 | - * @param beginPosition | |
89 | - * 開始位置 | |
90 | - * @param endPosition | |
91 | - * 終了位置 | |
92 | - */ | |
93 | - public void rangeDelimiter(String delimiter, int beginPosition, int endPosition); | |
94 | - | |
95 | - /** | |
96 | - * 記号 | |
97 | - * | |
98 | - * @param symbol | |
99 | - * 記号文字 | |
100 | - * @param beginPosition | |
101 | - * 開始位置 | |
102 | - * @param endPosition | |
103 | - * 終了位置 | |
104 | - */ | |
105 | - public void rangeSymbol(String symbol, int beginPosition, int endPosition); | |
106 | - | |
107 | - /** | |
108 | - * 終了 | |
109 | - * | |
110 | - * @param separateSentence | |
111 | - * 1SQLに分解されたSQL文 | |
112 | - * @param command | |
113 | - * SQL命令種類(SELECT,INSERT,DELETE,UPDATE,CREATE,ALTER,...) | |
114 | - */ | |
115 | - public void finished(String separateSentence, String command); | |
116 | - | |
117 | -} |
@@ -1,484 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService; | |
17 | - | |
18 | -import java.util.ArrayList; | |
19 | -import java.util.List; | |
20 | -import java.util.regex.Matcher; | |
21 | -import java.util.regex.Pattern; | |
22 | - | |
23 | -/** | |
24 | - * SQL文を字句要素に分解し、リスナーを通して要素種類毎に通知します。 字句要素は、下記6種類。 | |
25 | - * <ul> | |
26 | - * <li>comment ハイフン開始コメント及び スラッシュアスタリスク範囲領域のコメント | |
27 | - * <li>constant アスタリスク範囲領域の文字列定数 | |
28 | - * <li>symbol 記号 | |
29 | - * <li>delimiter 区切り文字 | |
30 | - * <li>input 入力パラメータ | |
31 | - * <li>phrase その他を全てSQL句と判定 | |
32 | - * </ul> | |
33 | - * 複数のSQL文を単一のSQLに分解するために、文区切りの正規表現にマッチした時に、リスナーを通じて分区切りを通知します。 | |
34 | - * その時のリスナーへの通知順は下記のようになります。 | |
35 | - * <ol> | |
36 | - * <li>{@link SqlSentenceListener#started(String)} | |
37 | - * <li>{@link SqlSentenceListener#finished(String, String)} | |
38 | - * <li> | |
39 | - * {@link SqlSentenceSparateListener#rangeSeparate(String, int, int, Pattern)} | |
40 | - * <li>{@link SqlSentenceListener#started(String)} | |
41 | - * <li>{@link SqlSentenceListener#finished(String, String)} | |
42 | - * </ol> | |
43 | - */ | |
44 | -public class SqlSentenceParse { | |
45 | - | |
46 | - private String sqlSentence; | |
47 | - | |
48 | - private Pattern separatePattern; | |
49 | - private SqlSentenceSparateListener sqlSentenceSparateListener; | |
50 | - private final List<SqlSentenceListener> listenerList = new ArrayList<SqlSentenceListener>(); | |
51 | - | |
52 | - /** | |
53 | - * 複数SQLを単一SQL文に分解するときの正規表現を登録する | |
54 | - * | |
55 | - * @param pattern | |
56 | - */ | |
57 | - public void registSeparatePattern(Pattern pattern) { | |
58 | - if (pattern == null) { | |
59 | - throw new NullPointerException(); | |
60 | - } | |
61 | - separatePattern = pattern; | |
62 | - } | |
63 | - | |
64 | - /** | |
65 | - * SQL文の区切りを通知するリスナーを登録する | |
66 | - * | |
67 | - * @param sqlSentenceSparateListener | |
68 | - */ | |
69 | - public void registSeparateListener(SqlSentenceSparateListener sqlSentenceSparateListener) { | |
70 | - this.sqlSentenceSparateListener = sqlSentenceSparateListener; | |
71 | - } | |
72 | - /** | |
73 | - * 字句要素解析結果通知リスナーを登録する | |
74 | - * | |
75 | - * @param listener | |
76 | - */ | |
77 | - public void addSqlSentenceListener(SqlSentenceListener listener) { | |
78 | - if (listener == null) { | |
79 | - throw new NullPointerException(); | |
80 | - } | |
81 | - listenerList.add(listener); | |
82 | - } | |
83 | - | |
84 | - /** | |
85 | - * 字句要素解析結果通知リスナーを削除する | |
86 | - */ | |
87 | - public void removeSqlSentenceListener(SqlSentenceListener listener) { | |
88 | - if (listener == null) { | |
89 | - throw new NullPointerException(); | |
90 | - } | |
91 | - listenerList.remove(listener); | |
92 | - } | |
93 | - | |
94 | - /** | |
95 | - * 字句要素解析結果通知リスナーを全削除する | |
96 | - */ | |
97 | - public void removeAllSqlSentenceListener() { | |
98 | - listenerList.clear(); | |
99 | - } | |
100 | - | |
101 | - /** | |
102 | - * SQL文を解析し、字句要素に応じて、リスナーのメソッドを呼び出す。 | |
103 | - * | |
104 | - * @param sqlSentence | |
105 | - */ | |
106 | - public void parse(String sqlSentence) { | |
107 | - this.sqlSentence = sqlSentence; | |
108 | - | |
109 | - int sentenceStartPosition = 0; | |
110 | - | |
111 | - State flg = State.PHRASE; | |
112 | - | |
113 | - // 解析開始の通知 | |
114 | - for (SqlSentenceListener l : listenerList) | |
115 | - l.started(sqlSentence); | |
116 | - | |
117 | - // 字句要素範囲を一時保管するオブジェクトの初期化 | |
118 | - RangePhrase rangePhrase = new RangePhrase(); | |
119 | - RangeComment rangeComment = new RangeComment(); | |
120 | - RangeConstant rangeConstant = new RangeConstant(); | |
121 | - RangeDelimiter rangeDelimiter = new RangeDelimiter(); | |
122 | - RangeSymbol rangeSymbol = new RangeSymbol(); | |
123 | - | |
124 | - // SQL文を1文字ずつ解析する | |
125 | - for (int i = 0; i < sqlSentence.length(); i++) { | |
126 | - | |
127 | - // コメントは、2文字を同時に判断する必要がある | |
128 | - char[] dst = new char[2]; | |
129 | - if (i == sqlSentence.length() - 1) { | |
130 | - sqlSentence.getChars(i, i + 1, dst, 0); | |
131 | - dst[1] = 0xff; | |
132 | - } else { | |
133 | - sqlSentence.getChars(i, i + 2, dst, 0); | |
134 | - } | |
135 | - | |
136 | - // 読み込み文字を判断し、現状態からどの状態に遷移すればよいか決定する。 | |
137 | - flg = flg.next(dst); | |
138 | - | |
139 | - // デリミタとSQL句は、終了文字が規定できないので、コメントや定数が始まったら終了とする。 | |
140 | - // コメントや定数は、明確な終了記号が存在すので、開始・途中・終了のそれぞれを状態として管理する。 | |
141 | - | |
142 | - if (flg == State.HIFUNCOMMENT_START || flg == State.SLASHCOMMENT_START) { | |
143 | - rangePhrase.end(i - 1); | |
144 | - rangeDelimiter.end(i - 1); | |
145 | - rangeComment.begin(i); | |
146 | - | |
147 | - } else if (flg == State.COMMENT_END) { | |
148 | - rangeComment.end(i); | |
149 | - | |
150 | - } else if (flg == State.APOST_START) { | |
151 | - rangePhrase.end(i - 1); | |
152 | - rangeDelimiter.end(i - 1); | |
153 | - rangeConstant.begin(i); | |
154 | - | |
155 | - } else if (flg == State.APOST_END) { | |
156 | - rangeConstant.end(i); | |
157 | - | |
158 | - } else if (flg == State.DELIMITER) { | |
159 | - rangePhrase.end(i - 1); | |
160 | - rangeDelimiter.begin(i); | |
161 | - | |
162 | - } else if (flg == State.PHRASE) { | |
163 | - rangeDelimiter.end(i - 1); | |
164 | - rangePhrase.begin(i); | |
165 | - | |
166 | - } else if (flg == State.SYMBOL_CHAR) { | |
167 | - rangeDelimiter.end(i - 1); | |
168 | - rangePhrase.end(i - 1); | |
169 | - rangeSymbol.begin(i); | |
170 | - rangeSymbol.end(i); | |
171 | - | |
172 | - } | |
173 | - | |
174 | - if (sqlSentenceSparateListener != null) { | |
175 | - if (flg == State.PHRASE || flg == State.SYMBOL_CHAR || flg == State.DELIMITER) { | |
176 | - int beginIndex = i; | |
177 | - int endIndex = i + 10; | |
178 | - if (endIndex > sqlSentence.length()) { | |
179 | - endIndex = sqlSentence.length(); | |
180 | - } | |
181 | - Matcher m = separatePattern.matcher(sqlSentence.substring(beginIndex, endIndex)); | |
182 | - if (m.lookingAt()) { | |
183 | - // 解析終了通知 | |
184 | - for (SqlSentenceListener l : listenerList) | |
185 | - l.finished(sqlSentence.substring(sentenceStartPosition, i), rangePhrase.getFirstSqlWord()); | |
186 | - | |
187 | - String matchKeyword = m.group(); | |
188 | - sqlSentenceSparateListener.rangeSeparate(matchKeyword, | |
189 | - i + m.start(), | |
190 | - i + m.end(), | |
191 | - separatePattern); | |
192 | - | |
193 | - rangePhrase.setFirstSqlWord(""); | |
194 | - i = i + m.end() - 1; | |
195 | - sentenceStartPosition = i; | |
196 | - // 解析開始の通知 | |
197 | - for (SqlSentenceListener l : listenerList) | |
198 | - l.started(sqlSentence.substring(i)); | |
199 | - } | |
200 | - } | |
201 | - } | |
202 | - | |
203 | - } | |
204 | - | |
205 | - // 中途半端な状態であったらその状態で終了させる。 | |
206 | - // 但し、どれか一つしかその対象にならない。 | |
207 | - // rangeSymbolは1文字だけであり、必ず閉じているので必要ない | |
208 | - rangePhrase.finish(); | |
209 | - rangeComment.finish(); | |
210 | - rangeConstant.finish(); | |
211 | - rangeDelimiter.finish(); | |
212 | - | |
213 | - // 解析終了通知 | |
214 | - for (SqlSentenceListener l : listenerList) | |
215 | - l.finished(sqlSentence.substring(sentenceStartPosition), rangePhrase.getFirstSqlWord()); | |
216 | - } | |
217 | - | |
218 | - /** | |
219 | - * 記号文字の集合 | |
220 | - */ | |
221 | - static final char[] SYMBOLS = { ',', '(', ')', '!', '+', '-', '*', '/', '=', '<', '>', ';' }; | |
222 | - | |
223 | - /** | |
224 | - * 現時点状態に対し、読み込み文字が次状態へ遷移すべきかを決定する。 | |
225 | - * 例えば、SQL句状態で、コメント開始文字(--や/*)を受け取ったら、コメント開始状態へ遷移する。 | |
226 | - */ | |
227 | - enum State { | |
228 | - PHRASE { | |
229 | - @Override | |
230 | - public State next(char[] dst) { | |
231 | - if (dst[0] == '/' && dst[1] == '*') | |
232 | - return SLASHCOMMENT_START; | |
233 | - if (dst[0] == '-' && dst[1] == '-') | |
234 | - return HIFUNCOMMENT_START; | |
235 | - if (dst[0] == '\'') | |
236 | - return APOST_START; | |
237 | - if (dst[0] == ' ' || dst[0] == '\t' || dst[0] == '\n') | |
238 | - return DELIMITER; | |
239 | - for (int i = 0; i < SYMBOLS.length; i++) { | |
240 | - if (dst[0] == SYMBOLS[i]) | |
241 | - return SYMBOL_CHAR; | |
242 | - } | |
243 | - return this; | |
244 | - } | |
245 | - }, | |
246 | - SYMBOL_CHAR { | |
247 | - @Override | |
248 | - public State next(char[] dst) { | |
249 | - return PHRASE.next(dst); | |
250 | - } | |
251 | - }, | |
252 | - | |
253 | - // APOST state | |
254 | - APOST_START { | |
255 | - @Override | |
256 | - public State next(char[] dst) { | |
257 | - if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] == '\'') | |
258 | - return APOST_ESCAPE; | |
259 | - if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] != '\'') | |
260 | - return APOST_END; | |
261 | - return APOST; | |
262 | - } | |
263 | - }, | |
264 | - APOST { | |
265 | - @Override | |
266 | - public State next(char[] dst) { | |
267 | - if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] == '\'') | |
268 | - return APOST_ESCAPE; | |
269 | - if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] != '\'') | |
270 | - return APOST_END; | |
271 | - return this; | |
272 | - } | |
273 | - }, | |
274 | - APOST_ESCAPE { | |
275 | - @Override | |
276 | - public State next(char[] dst) { | |
277 | - return APOST; | |
278 | - } | |
279 | - }, | |
280 | - APOST_END { | |
281 | - @Override | |
282 | - public State next(char[] dst) { | |
283 | - return PHRASE.next(dst); | |
284 | - } | |
285 | - }, | |
286 | - | |
287 | - // SLASH COMMENT state | |
288 | - SLASHCOMMENT_START { | |
289 | - @Override | |
290 | - public State next(char[] dst) { | |
291 | - return SLASHCOMMENT; | |
292 | - } | |
293 | - }, | |
294 | - SLASHCOMMENT { | |
295 | - @Override | |
296 | - public State next(char[] dst) { | |
297 | - if (dst[0] == '*' && dst[1] == '/') | |
298 | - return SLASHCOMMENT_PREEND; | |
299 | - return this; | |
300 | - } | |
301 | - }, | |
302 | - SLASHCOMMENT_PREEND { | |
303 | - @Override | |
304 | - public State next(char[] dst) { | |
305 | - return COMMENT_END; | |
306 | - } | |
307 | - }, | |
308 | - | |
309 | - // HIFUN COMMENT state | |
310 | - HIFUNCOMMENT_START { | |
311 | - @Override | |
312 | - public State next(char[] dst) { | |
313 | - return HIFUNCOMMENT; | |
314 | - } | |
315 | - }, | |
316 | - HIFUNCOMMENT { | |
317 | - @Override | |
318 | - public State next(char[] dst) { | |
319 | - if (dst[0] == '\n') | |
320 | - return COMMENT_END; | |
321 | - return this; | |
322 | - } | |
323 | - }, | |
324 | - | |
325 | - // COMMENT state end (SLASH and HIFUN) | |
326 | - COMMENT_END { | |
327 | - @Override | |
328 | - public State next(char[] dst) { | |
329 | - return PHRASE.next(dst); | |
330 | - } | |
331 | - }, | |
332 | - | |
333 | - // DELIMITER state | |
334 | - DELIMITER { | |
335 | - @Override | |
336 | - public State next(char[] dst) { | |
337 | - return PHRASE.next(dst); | |
338 | - } | |
339 | - }, | |
340 | - | |
341 | - ; | |
342 | - | |
343 | - public abstract State next(char[] dst); | |
344 | - } | |
345 | - | |
346 | - /** | |
347 | - * 各字句要素の開始位置と終了位置を管理する | |
348 | - * | |
349 | - * @author sima | |
350 | - * | |
351 | - */ | |
352 | - abstract class Range { | |
353 | - /** | |
354 | - * 範囲指定が有効状態であるかを示す | |
355 | - */ | |
356 | - boolean valid = false; | |
357 | - | |
358 | - int beginPosition = Integer.MIN_VALUE; | |
359 | - int endPosition = Integer.MAX_VALUE; | |
360 | - | |
361 | - private String firstSqlWord = ""; | |
362 | - | |
363 | - /** | |
364 | - * 開始位置を設定し有効状態にする。但し、既に有効の場合は、開始位置を設定せずに復帰する。 | |
365 | - * | |
366 | - * @param beginPosition | |
367 | - */ | |
368 | - void begin(int beginPosition) { | |
369 | - if (valid) { | |
370 | - return; | |
371 | - } | |
372 | - this.beginPosition = beginPosition; | |
373 | - valid = true; | |
374 | - } | |
375 | - | |
376 | - /** | |
377 | - * 開始位置が設定されており、終了が未設定の場合、残りの領域を全て強制終了する。 | |
378 | - * | |
379 | - * @param sqlSentence | |
380 | - * @param listeners | |
381 | - */ | |
382 | - void finish() { | |
383 | - if (!valid) { | |
384 | - return; | |
385 | - } | |
386 | - end(sqlSentence.length() - 1); | |
387 | - } | |
388 | - | |
389 | - /** | |
390 | - * 終了位置を設定し無効状態にする。登録されているリスナーを呼び出す為に各実装クラスのメソッドを呼び出す。 | |
391 | - * 但し、無効状態の場合は、何もせずに復帰する。 | |
392 | - * | |
393 | - * @param sqlSentence | |
394 | - * @param listeners | |
395 | - * @param endPosition | |
396 | - */ | |
397 | - void end(int endPosition) { | |
398 | - if (!valid) { | |
399 | - return; | |
400 | - } | |
401 | - | |
402 | - this.endPosition = endPosition; | |
403 | - String word = sqlSentence.substring(beginPosition, endPosition + 1); | |
404 | - | |
405 | - for (SqlSentenceListener l : listenerList) { | |
406 | - fire(l, word); | |
407 | - } | |
408 | - valid = false; | |
409 | - if (getFirstSqlWord().equals("")) { | |
410 | - setFirstSqlWord(word); | |
411 | - } | |
412 | - } | |
413 | - | |
414 | - /** | |
415 | - * リスナーを呼びだす。継承先クラスで呼出処理は実装する。 | |
416 | - * | |
417 | - * @param l | |
418 | - * リスナー | |
419 | - * @param s | |
420 | - * 通知文字列 | |
421 | - */ | |
422 | - abstract void fire(SqlSentenceListener l, String sqlWord); | |
423 | - | |
424 | - @Override | |
425 | - public String toString() { | |
426 | - return beginPosition + ":" + endPosition; | |
427 | - } | |
428 | - | |
429 | - /** | |
430 | - * @param firstSqlWord | |
431 | - * セットする firstSqlWord | |
432 | - */ | |
433 | - void setFirstSqlWord(String firstSqlWord) { | |
434 | - this.firstSqlWord = firstSqlWord; | |
435 | - } | |
436 | - | |
437 | - /** | |
438 | - * @return firstSqlWord | |
439 | - */ | |
440 | - String getFirstSqlWord() { | |
441 | - return firstSqlWord.toUpperCase(); | |
442 | - } | |
443 | - } | |
444 | - | |
445 | - class RangeComment extends Range { | |
446 | - @Override | |
447 | - void fire(SqlSentenceListener l, String sqlWord) { | |
448 | - l.rangeComment(sqlWord, beginPosition, endPosition); | |
449 | - } | |
450 | - } | |
451 | - | |
452 | - class RangePhrase extends Range { | |
453 | - @Override | |
454 | - void fire(SqlSentenceListener l, String sqlWord) { | |
455 | - if (sqlWord.startsWith(":") || sqlWord.equals("?")) { | |
456 | - l.rangeInput(sqlWord, beginPosition, endPosition); | |
457 | - } else { | |
458 | - l.rangePhrase(sqlWord, beginPosition, endPosition); | |
459 | - } | |
460 | - } | |
461 | - } | |
462 | - | |
463 | - class RangeConstant extends Range { | |
464 | - @Override | |
465 | - void fire(SqlSentenceListener l, String sqlWord) { | |
466 | - l.rangeConstant(sqlWord, beginPosition, endPosition); | |
467 | - } | |
468 | - } | |
469 | - | |
470 | - class RangeDelimiter extends Range { | |
471 | - @Override | |
472 | - void fire(SqlSentenceListener l, String sqlWord) { | |
473 | - l.rangeDelimiter(sqlWord, beginPosition, endPosition); | |
474 | - } | |
475 | - } | |
476 | - | |
477 | - class RangeSymbol extends Range { | |
478 | - @Override | |
479 | - void fire(SqlSentenceListener l, String sqlWord) { | |
480 | - l.rangeSymbol(sqlWord, beginPosition, endPosition); | |
481 | - } | |
482 | - } | |
483 | - | |
484 | -} |
@@ -1,40 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright 2011 Kazuhiro Shimada | |
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 | - | |
17 | -package jdbcacsess2.sqlService; | |
18 | - | |
19 | -import java.util.regex.Pattern; | |
20 | - | |
21 | -/** | |
22 | - * @author sima | |
23 | - * | |
24 | - */ | |
25 | -public interface SqlSentenceSparateListener { | |
26 | - /** | |
27 | - * SQL文セパレータ | |
28 | - * | |
29 | - * @param matchKeyword | |
30 | - * マッチ文字 | |
31 | - * @param beginPosition | |
32 | - * 開始位置 | |
33 | - * @param endPosition | |
34 | - * 終了位置 | |
35 | - * @param pattern | |
36 | - * マッチ時の正規表現 | |
37 | - */ | |
38 | - public void rangeSeparate(String matchKeyword, int beginPosition, int endPosition, Pattern pattern); | |
39 | - | |
40 | -} |
@@ -0,0 +1,66 @@ | ||
1 | +/* | |
2 | + * Copyright 2011 Kazuhiro Shimada | |
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 | + | |
17 | +package jdbcacsess2.sqlService.dbobject; | |
18 | + | |
19 | +import java.util.List; | |
20 | + | |
21 | +import javax.swing.table.AbstractTableModel; | |
22 | + | |
23 | +import jdbcacsess2.sqlService.dbobject.DBObject.Property; | |
24 | + | |
25 | +/** | |
26 | + * @author sima | |
27 | + * | |
28 | + */ | |
29 | +public class PropertyDBObjectsTableModel extends AbstractTableModel { | |
30 | + private static final long serialVersionUID = 3293479625219161204L; | |
31 | + | |
32 | + private final List<Property> properties; | |
33 | + | |
34 | + public PropertyDBObjectsTableModel(List<Property> properties) { | |
35 | + this.properties = properties; | |
36 | + } | |
37 | + | |
38 | + @Override | |
39 | + public int getColumnCount() { | |
40 | + return 2; | |
41 | + } | |
42 | + | |
43 | + @Override | |
44 | + public int getRowCount() { | |
45 | + return properties.size(); | |
46 | + } | |
47 | + | |
48 | + @Override | |
49 | + public String getColumnName(int column) { | |
50 | + if (column == 0) { | |
51 | + return "name"; | |
52 | + } else { | |
53 | + return "value"; | |
54 | + } | |
55 | + } | |
56 | + | |
57 | + @Override | |
58 | + public Object getValueAt(int rowIndex, int columnIndex) { | |
59 | + if (columnIndex == 0) { | |
60 | + return properties.get(rowIndex).getName(); | |
61 | + } else { | |
62 | + return properties.get(rowIndex).getValue(); | |
63 | + } | |
64 | + } | |
65 | +} | |
66 | + |
@@ -0,0 +1,127 @@ | ||
1 | +/* | |
2 | + * Copyright 2011 Kazuhiro Shimada | |
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 | + | |
17 | +package jdbcacsess2.sqlService.dbobject; | |
18 | + | |
19 | +import java.util.List; | |
20 | + | |
21 | +import javax.swing.table.AbstractTableModel; | |
22 | + | |
23 | +import jdbcacsess2.sqlService.ReferenceColumnResult; | |
24 | + | |
25 | +/** | |
26 | + * @author sima | |
27 | + * | |
28 | + */ | |
29 | +public class PropertyExportedKeyTableModel extends AbstractTableModel { | |
30 | + private static final long serialVersionUID = 6816351858372050538L; | |
31 | + private List<ReferenceColumnResult> exportKey; | |
32 | + | |
33 | + public PropertyExportedKeyTableModel(List<ReferenceColumnResult> exportKey) { | |
34 | + this.exportKey = exportKey; | |
35 | + } | |
36 | + | |
37 | + @Override | |
38 | + public int getColumnCount() { | |
39 | + return 14; | |
40 | + } | |
41 | + | |
42 | + @Override | |
43 | + public int getRowCount() { | |
44 | + return exportKey.size(); | |
45 | + } | |
46 | + | |
47 | + @Override | |
48 | + public String getColumnName(int column) { | |
49 | + switch (column) { | |
50 | + case 0: | |
51 | + return "PKcat"; | |
52 | + case 1: | |
53 | + return "PKschem"; | |
54 | + case 2: | |
55 | + return "PKtable"; | |
56 | + case 3: | |
57 | + return "PKname"; | |
58 | + case 4: | |
59 | + return "PKcolumn"; | |
60 | + | |
61 | + case 5: | |
62 | + return "FKcat"; | |
63 | + case 6: | |
64 | + return "FKschem"; | |
65 | + case 7: | |
66 | + return "FKtable"; | |
67 | + case 8: | |
68 | + return "FKname"; | |
69 | + case 9: | |
70 | + return "FKcolumn"; | |
71 | + | |
72 | + case 10: | |
73 | + return "KeySeq"; | |
74 | + | |
75 | + case 11: | |
76 | + return "UpdateRule"; | |
77 | + case 12: | |
78 | + return "DeleteRule"; | |
79 | + | |
80 | + case 13: | |
81 | + return "Deferrability"; | |
82 | + } | |
83 | + return ""; | |
84 | + } | |
85 | + | |
86 | + @Override | |
87 | + public Object getValueAt(int rowIndex, int columnIndex) { | |
88 | + ReferenceColumnResult r = exportKey.get(rowIndex); | |
89 | + | |
90 | + switch (columnIndex) { | |
91 | + case 0: | |
92 | + return r.getPktableCat(); | |
93 | + case 1: | |
94 | + return r.getPktableSchem(); | |
95 | + case 2: | |
96 | + return r.getPktableName(); | |
97 | + case 3: | |
98 | + return r.getPkName(); | |
99 | + case 4: | |
100 | + return r.getPkcolumnName(); | |
101 | + | |
102 | + case 5: | |
103 | + return r.getFktableCat(); | |
104 | + case 6: | |
105 | + return r.getFktableSchem(); | |
106 | + case 7: | |
107 | + return r.getFktableName(); | |
108 | + case 8: | |
109 | + return r.getFkName(); | |
110 | + case 9: | |
111 | + return r.getFkcolumnName(); | |
112 | + | |
113 | + case 10: | |
114 | + return r.getKeySeq(); | |
115 | + | |
116 | + case 11: | |
117 | + return r.getUpdateRuleName(); | |
118 | + case 12: | |
119 | + return r.getDeleteRuleName(); | |
120 | + | |
121 | + case 13: | |
122 | + return r.getDeferrabilityName(); | |
123 | + } | |
124 | + return null; | |
125 | + } | |
126 | + | |
127 | +} |
@@ -25,10 +25,10 @@ | ||
25 | 25 | import jdbcacsess2.main.Config; |
26 | 26 | import jdbcacsess2.main.ShowDialog; |
27 | 27 | import jdbcacsess2.sqlService.ColumnAttributeResult; |
28 | -import jdbcacsess2.sqlService.SqlExecuteSentencies.SqlExecuteSentence; | |
29 | 28 | import jdbcacsess2.sqlService.SqlExecuteTask; |
30 | 29 | import jdbcacsess2.sqlService.SqlExecutedListener; |
31 | 30 | import jdbcacsess2.sqlService.history.ExecHistory.ResultStatus; |
31 | +import jdbcacsess2.sqlService.parse.SqlExecuteSentencies.SqlExecuteSentence; | |
32 | 32 | import net.java.ao.DBParam; |
33 | 33 | import net.java.ao.EntityManager; |
34 | 34 |
@@ -0,0 +1,243 @@ | ||
1 | +/* | |
2 | + * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService.parse; | |
17 | + | |
18 | +import java.util.ArrayList; | |
19 | +import java.util.regex.Pattern; | |
20 | + | |
21 | +import jdbcacsess2.main.Jdbcacsess2; | |
22 | + | |
23 | +/** | |
24 | + * SQL文を解析し、最初の命令句/入力変数/更新可能SELECT文であるか?などを抽出します。 | |
25 | + * | |
26 | + * 画面から入力されたSQLが複数文であった場合、1SQL文毎に分解されます。 SQL文の区切りは{@link SqlSentenceParse} | |
27 | + * で行われるので、通知されたSQL文の番号を使用して、それぞれのSQL文を区別します。 | |
28 | + * | |
29 | + * @author sima | |
30 | + * | |
31 | + */ | |
32 | +public class SqlExecuteSentencies { | |
33 | + | |
34 | + /** | |
35 | + * コンストラクタ、SQL文のparseを行う。 | |
36 | + * | |
37 | + * @param sqlSentence | |
38 | + * 分析したいSQL文 | |
39 | + * @param sentenceSeparator | |
40 | + * 複数SQL文を区切り正規表現文字列 | |
41 | + */ | |
42 | + public SqlExecuteSentencies(String sqlSentence, String sentenceSeparator) { | |
43 | + | |
44 | + | |
45 | + final SqlSentenceParse sqlSentenceParse = new SqlSentenceParse(); | |
46 | + | |
47 | + sqlSentenceParse.addSqlSentenceListener(new SqlExecuteSentence()); | |
48 | + | |
49 | + sqlSentenceParse.registSeparatePattern(Pattern.compile(sentenceSeparator)); | |
50 | + sqlSentenceParse.registSeparateListener(new SqlSentenceSparateListener() { | |
51 | + @Override | |
52 | + public void rangeSeparate(String matchKeyword, | |
53 | + int beginPosition, | |
54 | + int endPosition, | |
55 | + Pattern pattern) { | |
56 | + sqlSentenceParse.removeAllSqlSentenceListener(); | |
57 | + sqlSentenceParse.addSqlSentenceListener(new SqlExecuteSentence()); | |
58 | + } | |
59 | + }); | |
60 | + | |
61 | + // 解析開始 | |
62 | + sqlSentenceParse.parse(sqlSentence); | |
63 | + | |
64 | + Jdbcacsess2.logger.info(sqlExecuteSentenceList.toString()); | |
65 | + } | |
66 | + | |
67 | + private int seq = 0; | |
68 | + final private ArrayList<SqlExecuteSentence> sqlExecuteSentenceList = new ArrayList<SqlExecuteSentence>(); | |
69 | + | |
70 | + /** | |
71 | + * SQL文単位に分解された最終結果 | |
72 | + * | |
73 | + * @return SQL文解析結果のリスト | |
74 | + */ | |
75 | + public ArrayList<SqlExecuteSentence> getSqlExecuteSentenceList() { | |
76 | + return sqlExecuteSentenceList; | |
77 | + } | |
78 | + | |
79 | + /** | |
80 | + * 分解された1SQL文の解析結果 | |
81 | + * | |
82 | + * @author sima | |
83 | + * | |
84 | + */ | |
85 | + public class SqlExecuteSentence implements SqlSentenceListener { | |
86 | + | |
87 | + private String sqlSentence; | |
88 | + private int sentenceCount; | |
89 | + | |
90 | + /** | |
91 | + * SQLの連番 | |
92 | + * | |
93 | + * @return sentenceCount | |
94 | + */ | |
95 | + public int getSentenceCount() { | |
96 | + return sentenceCount; | |
97 | + } | |
98 | + | |
99 | + /** | |
100 | + * SQL文 | |
101 | + * | |
102 | + * @return sqlSentence | |
103 | + */ | |
104 | + public String getSqlSentence() { | |
105 | + return sqlSentence; | |
106 | + } | |
107 | + | |
108 | + private final SqlInputParameter sqlInputParameter = new SqlInputParameter(); | |
109 | + | |
110 | + /** | |
111 | + * 入力パラメータ | |
112 | + * | |
113 | + * @return sqlInputParameter | |
114 | + */ | |
115 | + public SqlInputParameter getSqlInputParameter() { | |
116 | + return sqlInputParameter; | |
117 | + } | |
118 | + | |
119 | + private String sqlCommand; | |
120 | + | |
121 | + /** | |
122 | + * SQL文の最初の命令句 | |
123 | + * | |
124 | + * @return "SELECT","INSERT"."DELETE","CALL","CREATE","ALTER"等の文字列。 | |
125 | + * 常に大文字で返却されます 。 | |
126 | + */ | |
127 | + public String getSqlCommand() { | |
128 | + return sqlCommand; | |
129 | + } | |
130 | + | |
131 | + private boolean editable = false; | |
132 | + | |
133 | + /** | |
134 | + * 更新可能SELECT文であるか | |
135 | + * | |
136 | + * @return editable | |
137 | + */ | |
138 | + public boolean isEditable() { | |
139 | + return editable; | |
140 | + } | |
141 | + | |
142 | + private int phraseCnt = 0; | |
143 | + private boolean checkEnd = false; | |
144 | + private boolean select = false; | |
145 | + private boolean from = false; | |
146 | + | |
147 | + @Override | |
148 | + public void started(String sqlSentence) { | |
149 | + // finished で上書きされるの意味はない | |
150 | + this.sqlSentence = sqlSentence; | |
151 | + } | |
152 | + | |
153 | + @Override | |
154 | + public void rangeInput(String phrase, int begin, int end) { | |
155 | + sqlInputParameter.addInputItemName(phrase); | |
156 | + } | |
157 | + | |
158 | + @Override | |
159 | + public void rangePhrase(String phrase, int begin, int end) { | |
160 | + if (checkEnd) { | |
161 | + return; | |
162 | + } | |
163 | + String upperPhrase = phrase.toUpperCase(); | |
164 | + | |
165 | + phraseCnt++; | |
166 | + if (phraseCnt == 1 && upperPhrase.equals("SELECT")) { | |
167 | + select = true; | |
168 | + return; | |
169 | + } | |
170 | + if (!select) { | |
171 | + checkEnd = true; | |
172 | + editable = false; | |
173 | + return; | |
174 | + } | |
175 | + if (upperPhrase.equals("SELECT") || upperPhrase.equals("GROUP")) { | |
176 | + checkEnd = true; | |
177 | + editable = false; | |
178 | + return; | |
179 | + } | |
180 | + | |
181 | + if (upperPhrase.equals("FROM")) { | |
182 | + // FROM句を見つけたので、とりあえず更新可能とする | |
183 | + editable = true; | |
184 | + | |
185 | + from = true; | |
186 | + return; | |
187 | + } | |
188 | + if (upperPhrase.equals("WHERE")) { | |
189 | + from = false; | |
190 | + return; | |
191 | + } | |
192 | + | |
193 | + } | |
194 | + | |
195 | + @Override | |
196 | + public void rangeSymbol(String symbol, int begin, int end) { | |
197 | + if (checkEnd) { | |
198 | + return; | |
199 | + } | |
200 | + if (from && symbol.equals(",")) { | |
201 | + // FROM句中にカンマを見つけたので、更新不可が確定した | |
202 | + checkEnd = true; | |
203 | + editable = false; | |
204 | + return; | |
205 | + } | |
206 | + } | |
207 | + | |
208 | + @Override | |
209 | + public void finished(String sentence, String command) { | |
210 | + sqlSentence = sentence; | |
211 | + sqlCommand = command; | |
212 | + if (!sqlCommand.equals("")) { | |
213 | + sentenceCount = ++seq; | |
214 | + if (sqlCommand.equals("CREATE") || sqlCommand.equals("ALTER")) { | |
215 | + sqlInputParameter.clear(); | |
216 | + } | |
217 | + sqlExecuteSentenceList.add(this); | |
218 | + } | |
219 | + } | |
220 | + | |
221 | + @Override | |
222 | + public void rangeComment(String comment, int begin, int end) { | |
223 | + } | |
224 | + | |
225 | + @Override | |
226 | + public void rangeConstant(String constant, int begin, int end) { | |
227 | + } | |
228 | + | |
229 | + @Override | |
230 | + public void rangeDelimiter(String delimiter, int begin, int end) { | |
231 | + } | |
232 | + | |
233 | + @Override | |
234 | + public String toString() { | |
235 | + return "command:" + sqlCommand + " editable:" + editable + " inputItems:" | |
236 | + + sqlInputParameter.getInputItemNames() + "[" | |
237 | + + sqlSentence + "]"; | |
238 | + } | |
239 | + | |
240 | + } | |
241 | + | |
242 | + | |
243 | +} |
@@ -0,0 +1,152 @@ | ||
1 | +/* | |
2 | + * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService.parse; | |
17 | + | |
18 | +import java.util.ArrayList; | |
19 | +import java.util.HashMap; | |
20 | + | |
21 | +import jdbcacsess2.sqlService.ConstSqlTypes; | |
22 | +import jdbcacsess2.sqlService.SqlExecuteParmeter; | |
23 | +import jdbcacsess2.sqlService.SqlExecuteParmeter.Parameter; | |
24 | + | |
25 | +/** | |
26 | + * | |
27 | + * SQL文の入力パラメータに関する情報を、1つの実行SQL文分だけ集めたクラスです。 | |
28 | + * 1SQL文には複数のパラメータが想定されるので、それぞれの内容はArrayListでリスト化されています。 | |
29 | + * <ul> | |
30 | + * <li>SQL文中に記述された入力パラメータの名称:{@link SqlExecuteSentencies.SqlExecuteSentence} | |
31 | + * が解析した結果を格納する事を想定しています。 | |
32 | + * <li>入力パラメータの値とそのSQLTYPE:3パターンの使い方が出来ます。 | |
33 | + * <ol> | |
34 | + * <li>パラメータが無い | |
35 | + * <li>入力パラメータを指定しSQLを1回だけ実行する時 | |
36 | + * <li>1つのSQLで入力パラメータを切り替えながら順次実行する | |
37 | + * </ol> | |
38 | + * 3番目の使用方法は、PrepareしたSQL文に対して、入力パラメータの設定とexecuteが、複数回実行されるイメージです。 | |
39 | + * </ul> | |
40 | + * | |
41 | + * @author sima | |
42 | + * | |
43 | + */ | |
44 | +public class SqlInputParameter { | |
45 | + | |
46 | + private final Parameter parameter; | |
47 | + | |
48 | + public SqlInputParameter() { | |
49 | + parameter = new SqlExecuteParmeter.Parameter(); | |
50 | + parameter.values = new ArrayList<Object>(); | |
51 | + parameter.sqlTypes = new HashMap<Integer, ConstSqlTypes>(); | |
52 | + } | |
53 | + | |
54 | + /** | |
55 | + * 入力パラメータ名のSQL文字句要素 | |
56 | + */ | |
57 | + final private ArrayList<String> inputItemNames = new ArrayList<String>(); | |
58 | + | |
59 | + /** | |
60 | + * 入力パラメータ名のSQL文字句要素を返却します。このリストの順番に | |
61 | + * {@link SqlInputParameter#addParameter(Object, ConstSqlTypes)} | |
62 | + * でパラメータを設定する必要があります。 | |
63 | + * | |
64 | + * @return | |
65 | + */ | |
66 | + public ArrayList<String> getInputItemNames() { | |
67 | + return inputItemNames; | |
68 | + } | |
69 | + | |
70 | + /** | |
71 | + * 入力パラメータ名のSQL文字句要素を追加します。これは、{@link SqlExecuteSentencies}が結果格納する時に使用されます。 | |
72 | + * | |
73 | + * @param inputItemName | |
74 | + */ | |
75 | + void addInputItemName(String inputItemName) { | |
76 | + inputItemNames.add(inputItemName); | |
77 | + } | |
78 | + | |
79 | + /** | |
80 | + * パラメータの値とタイプをパラメータリストの最後に追加します。 | |
81 | + * | |
82 | + * @param value | |
83 | + * 値 | |
84 | + * @param constSqlType | |
85 | + * 値のSQLTYPE | |
86 | + */ | |
87 | + public void addParameter(Object value, ConstSqlTypes constSqlType) { | |
88 | + addParameter(parameter.values.size() - 1, value, constSqlType); | |
89 | + } | |
90 | + | |
91 | + /** | |
92 | + * パラメータの値とタイプをパラメータリストの順番を指定して追加します。 | |
93 | + * | |
94 | + * @param index | |
95 | + * {@link SqlInputParameter#inputItemNames}のリストに存在するindex | |
96 | + * @param value | |
97 | + * 値 | |
98 | + * @param constSqlType | |
99 | + * 値のSQLTYPE | |
100 | + */ | |
101 | + public void addParameter(Integer index, Object value, ConstSqlTypes constSqlType) { | |
102 | + inputItemNames.get(index); // check | |
103 | + | |
104 | + parameter.values.add(value); | |
105 | + parameter.sqlTypes.put(index, constSqlType); | |
106 | + } | |
107 | + | |
108 | + public SqlExecuteParmeter getSqlExecuteParmeter() { | |
109 | + return sqlExecuteParmeter; | |
110 | + } | |
111 | + | |
112 | + /** | |
113 | + * デフォルトではパラメータ値は通常1SQLで1組となっています。<br> | |
114 | + * 同一SQLで複数組を処理したい場合、値とSQLTYPEを順次外部から与える方法を指定出来ます。 | |
115 | + * | |
116 | + * @param sqlExecuteParmeter | |
117 | + * {@link SqlExecuteParmeter}を実装した値とSQLTYPEの生成器。 | |
118 | + */ | |
119 | + public void setSqlExecuteParmeter(SqlExecuteParmeter sqlExecuteParmeter) { | |
120 | + this.sqlExecuteParmeter = sqlExecuteParmeter; | |
121 | + } | |
122 | + | |
123 | + private SqlExecuteParmeter sqlExecuteParmeter = new SqlExecuteParmeter() { | |
124 | + | |
125 | + boolean flg = true; | |
126 | + | |
127 | + @Override | |
128 | + public boolean hasNext() { | |
129 | + // 1回目の呼出はtrue、2回目以降はfalse | |
130 | + if (flg) { | |
131 | + flg = false; | |
132 | + return true; | |
133 | + } | |
134 | + return false; | |
135 | + } | |
136 | + | |
137 | + @Override | |
138 | + public Parameter getParameter() { | |
139 | + return parameter; | |
140 | + } | |
141 | + }; | |
142 | + | |
143 | + /** | |
144 | + * 入力パラメータ名とパラメータ値を全て初期化します。 | |
145 | + */ | |
146 | + public void clear() { | |
147 | + inputItemNames.clear(); | |
148 | + parameter.values.clear(); | |
149 | + parameter.sqlTypes.clear(); | |
150 | + } | |
151 | + | |
152 | +} |
@@ -0,0 +1,117 @@ | ||
1 | +/* | |
2 | + * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService.parse; | |
17 | + | |
18 | + | |
19 | +/** | |
20 | + * SQL文を解析した結果の字句要素を通知するリスナーです。 | |
21 | + * | |
22 | + * @author sima | |
23 | + * | |
24 | + */ | |
25 | +public interface SqlSentenceListener { | |
26 | + | |
27 | + /** | |
28 | + * 処理開始 | |
29 | + * | |
30 | + * @param sqlSentence | |
31 | + * 解析対象のSQL文 | |
32 | + */ | |
33 | + public void started(String sqlSentence); | |
34 | + | |
35 | + /** | |
36 | + * コメント | |
37 | + * | |
38 | + * @param comment | |
39 | + * コメント文字列 | |
40 | + * @param beginPosition | |
41 | + * 開始位置 | |
42 | + * @param endPosition | |
43 | + * 終了位置 | |
44 | + */ | |
45 | + public void rangeComment(String comment, int beginPosition, int endPosition); | |
46 | + | |
47 | + /** | |
48 | + * SQL句と要素 | |
49 | + * | |
50 | + * @param phrase | |
51 | + * SQL句と要素文字列 | |
52 | + * @param beginPosition | |
53 | + * 開始位置 | |
54 | + * @param endPosition | |
55 | + * 終了位置 | |
56 | + */ | |
57 | + public void rangePhrase(String phrase, int beginPosition, int endPosition); | |
58 | + | |
59 | + /** | |
60 | + * SQL句と要素 | |
61 | + * | |
62 | + * @param input | |
63 | + * SQL句と要素文字列 | |
64 | + * @param beginPosition | |
65 | + * 開始位置 | |
66 | + * @param endPosition | |
67 | + * 終了位置 | |
68 | + */ | |
69 | + public void rangeInput(String input, int beginPosition, int endPosition); | |
70 | + | |
71 | + /** | |
72 | + * 定数 | |
73 | + * | |
74 | + * @param constant | |
75 | + * 定数 | |
76 | + * @param beginPosition | |
77 | + * 開始位置 | |
78 | + * @param endPosition | |
79 | + * 終了位置 | |
80 | + */ | |
81 | + public void rangeConstant(String constant, int beginPosition, int endPosition); | |
82 | + | |
83 | + /** | |
84 | + * デリミタ | |
85 | + * | |
86 | + * @param delimiter | |
87 | + * デリミタ文字列 | |
88 | + * @param beginPosition | |
89 | + * 開始位置 | |
90 | + * @param endPosition | |
91 | + * 終了位置 | |
92 | + */ | |
93 | + public void rangeDelimiter(String delimiter, int beginPosition, int endPosition); | |
94 | + | |
95 | + /** | |
96 | + * 記号 | |
97 | + * | |
98 | + * @param symbol | |
99 | + * 記号文字 | |
100 | + * @param beginPosition | |
101 | + * 開始位置 | |
102 | + * @param endPosition | |
103 | + * 終了位置 | |
104 | + */ | |
105 | + public void rangeSymbol(String symbol, int beginPosition, int endPosition); | |
106 | + | |
107 | + /** | |
108 | + * 終了 | |
109 | + * | |
110 | + * @param separateSentence | |
111 | + * 1SQLに分解されたSQL文 | |
112 | + * @param command | |
113 | + * SQL命令種類(SELECT,INSERT,DELETE,UPDATE,CREATE,ALTER,...) | |
114 | + */ | |
115 | + public void finished(String separateSentence, String command); | |
116 | + | |
117 | +} |
@@ -0,0 +1,484 @@ | ||
1 | +/* | |
2 | + * Copyright 2011 Kazuhiro Shimada | |
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 jdbcacsess2.sqlService.parse; | |
17 | + | |
18 | +import java.util.ArrayList; | |
19 | +import java.util.List; | |
20 | +import java.util.regex.Matcher; | |
21 | +import java.util.regex.Pattern; | |
22 | + | |
23 | +/** | |
24 | + * SQL文を字句要素に分解し、リスナーを通して要素種類毎に通知します。 字句要素は、下記6種類。 | |
25 | + * <ul> | |
26 | + * <li>comment ハイフン開始コメント及び スラッシュアスタリスク範囲領域のコメント | |
27 | + * <li>constant アスタリスク範囲領域の文字列定数 | |
28 | + * <li>symbol 記号 | |
29 | + * <li>delimiter 区切り文字 | |
30 | + * <li>input 入力パラメータ | |
31 | + * <li>phrase その他を全てSQL句と判定 | |
32 | + * </ul> | |
33 | + * 複数のSQL文を単一のSQLに分解するために、文区切りの正規表現にマッチした時に、リスナーを通じて分区切りを通知します。 | |
34 | + * その時のリスナーへの通知順は下記のようになります。 | |
35 | + * <ol> | |
36 | + * <li>{@link SqlSentenceListener#started(String)} | |
37 | + * <li>{@link SqlSentenceListener#finished(String, String)} | |
38 | + * <li> | |
39 | + * {@link SqlSentenceSparateListener#rangeSeparate(String, int, int, Pattern)} | |
40 | + * <li>{@link SqlSentenceListener#started(String)} | |
41 | + * <li>{@link SqlSentenceListener#finished(String, String)} | |
42 | + * </ol> | |
43 | + */ | |
44 | +public class SqlSentenceParse { | |
45 | + | |
46 | + private String sqlSentence; | |
47 | + | |
48 | + private Pattern separatePattern; | |
49 | + private SqlSentenceSparateListener sqlSentenceSparateListener; | |
50 | + private final List<SqlSentenceListener> listenerList = new ArrayList<SqlSentenceListener>(); | |
51 | + | |
52 | + /** | |
53 | + * 複数SQLを単一SQL文に分解するときの正規表現を登録する | |
54 | + * | |
55 | + * @param pattern | |
56 | + */ | |
57 | + public void registSeparatePattern(Pattern pattern) { | |
58 | + if (pattern == null) { | |
59 | + throw new NullPointerException(); | |
60 | + } | |
61 | + separatePattern = pattern; | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * SQL文の区切りを通知するリスナーを登録する | |
66 | + * | |
67 | + * @param sqlSentenceSparateListener | |
68 | + */ | |
69 | + public void registSeparateListener(SqlSentenceSparateListener sqlSentenceSparateListener) { | |
70 | + this.sqlSentenceSparateListener = sqlSentenceSparateListener; | |
71 | + } | |
72 | + /** | |
73 | + * 字句要素解析結果通知リスナーを登録する | |
74 | + * | |
75 | + * @param listener | |
76 | + */ | |
77 | + public void addSqlSentenceListener(SqlSentenceListener listener) { | |
78 | + if (listener == null) { | |
79 | + throw new NullPointerException(); | |
80 | + } | |
81 | + listenerList.add(listener); | |
82 | + } | |
83 | + | |
84 | + /** | |
85 | + * 字句要素解析結果通知リスナーを削除する | |
86 | + */ | |
87 | + public void removeSqlSentenceListener(SqlSentenceListener listener) { | |
88 | + if (listener == null) { | |
89 | + throw new NullPointerException(); | |
90 | + } | |
91 | + listenerList.remove(listener); | |
92 | + } | |
93 | + | |
94 | + /** | |
95 | + * 字句要素解析結果通知リスナーを全削除する | |
96 | + */ | |
97 | + public void removeAllSqlSentenceListener() { | |
98 | + listenerList.clear(); | |
99 | + } | |
100 | + | |
101 | + /** | |
102 | + * SQL文を解析し、字句要素に応じて、リスナーのメソッドを呼び出す。 | |
103 | + * | |
104 | + * @param sqlSentence | |
105 | + */ | |
106 | + public void parse(String sqlSentence) { | |
107 | + this.sqlSentence = sqlSentence; | |
108 | + | |
109 | + int sentenceStartPosition = 0; | |
110 | + | |
111 | + State flg = State.PHRASE; | |
112 | + | |
113 | + // 解析開始の通知 | |
114 | + for (SqlSentenceListener l : listenerList) | |
115 | + l.started(sqlSentence); | |
116 | + | |
117 | + // 字句要素範囲を一時保管するオブジェクトの初期化 | |
118 | + RangePhrase rangePhrase = new RangePhrase(); | |
119 | + RangeComment rangeComment = new RangeComment(); | |
120 | + RangeConstant rangeConstant = new RangeConstant(); | |
121 | + RangeDelimiter rangeDelimiter = new RangeDelimiter(); | |
122 | + RangeSymbol rangeSymbol = new RangeSymbol(); | |
123 | + | |
124 | + // SQL文を1文字ずつ解析する | |
125 | + for (int i = 0; i < sqlSentence.length(); i++) { | |
126 | + | |
127 | + // コメントは、2文字を同時に判断する必要がある | |
128 | + char[] dst = new char[2]; | |
129 | + if (i == sqlSentence.length() - 1) { | |
130 | + sqlSentence.getChars(i, i + 1, dst, 0); | |
131 | + dst[1] = 0xff; | |
132 | + } else { | |
133 | + sqlSentence.getChars(i, i + 2, dst, 0); | |
134 | + } | |
135 | + | |
136 | + // 読み込み文字を判断し、現状態からどの状態に遷移すればよいか決定する。 | |
137 | + flg = flg.next(dst); | |
138 | + | |
139 | + // デリミタとSQL句は、終了文字が規定できないので、コメントや定数が始まったら終了とする。 | |
140 | + // コメントや定数は、明確な終了記号が存在すので、開始・途中・終了のそれぞれを状態として管理する。 | |
141 | + | |
142 | + if (flg == State.HIFUNCOMMENT_START || flg == State.SLASHCOMMENT_START) { | |
143 | + rangePhrase.end(i - 1); | |
144 | + rangeDelimiter.end(i - 1); | |
145 | + rangeComment.begin(i); | |
146 | + | |
147 | + } else if (flg == State.COMMENT_END) { | |
148 | + rangeComment.end(i); | |
149 | + | |
150 | + } else if (flg == State.APOST_START) { | |
151 | + rangePhrase.end(i - 1); | |
152 | + rangeDelimiter.end(i - 1); | |
153 | + rangeConstant.begin(i); | |
154 | + | |
155 | + } else if (flg == State.APOST_END) { | |
156 | + rangeConstant.end(i); | |
157 | + | |
158 | + } else if (flg == State.DELIMITER) { | |
159 | + rangePhrase.end(i - 1); | |
160 | + rangeDelimiter.begin(i); | |
161 | + | |
162 | + } else if (flg == State.PHRASE) { | |
163 | + rangeDelimiter.end(i - 1); | |
164 | + rangePhrase.begin(i); | |
165 | + | |
166 | + } else if (flg == State.SYMBOL_CHAR) { | |
167 | + rangeDelimiter.end(i - 1); | |
168 | + rangePhrase.end(i - 1); | |
169 | + rangeSymbol.begin(i); | |
170 | + rangeSymbol.end(i); | |
171 | + | |
172 | + } | |
173 | + | |
174 | + if (sqlSentenceSparateListener != null) { | |
175 | + if (flg == State.PHRASE || flg == State.SYMBOL_CHAR || flg == State.DELIMITER) { | |
176 | + int beginIndex = i; | |
177 | + int endIndex = i + 10; | |
178 | + if (endIndex > sqlSentence.length()) { | |
179 | + endIndex = sqlSentence.length(); | |
180 | + } | |
181 | + Matcher m = separatePattern.matcher(sqlSentence.substring(beginIndex, endIndex)); | |
182 | + if (m.lookingAt()) { | |
183 | + // 解析終了通知 | |
184 | + for (SqlSentenceListener l : listenerList) | |
185 | + l.finished(sqlSentence.substring(sentenceStartPosition, i), rangePhrase.getFirstSqlWord()); | |
186 | + | |
187 | + String matchKeyword = m.group(); | |
188 | + sqlSentenceSparateListener.rangeSeparate(matchKeyword, | |
189 | + i + m.start(), | |
190 | + i + m.end(), | |
191 | + separatePattern); | |
192 | + | |
193 | + rangePhrase.setFirstSqlWord(""); | |
194 | + i = i + m.end() - 1; | |
195 | + sentenceStartPosition = i; | |
196 | + // 解析開始の通知 | |
197 | + for (SqlSentenceListener l : listenerList) | |
198 | + l.started(sqlSentence.substring(i)); | |
199 | + } | |
200 | + } | |
201 | + } | |
202 | + | |
203 | + } | |
204 | + | |
205 | + // 中途半端な状態であったらその状態で終了させる。 | |
206 | + // 但し、どれか一つしかその対象にならない。 | |
207 | + // rangeSymbolは1文字だけであり、必ず閉じているので必要ない | |
208 | + rangePhrase.finish(); | |
209 | + rangeComment.finish(); | |
210 | + rangeConstant.finish(); | |
211 | + rangeDelimiter.finish(); | |
212 | + | |
213 | + // 解析終了通知 | |
214 | + for (SqlSentenceListener l : listenerList) | |
215 | + l.finished(sqlSentence.substring(sentenceStartPosition), rangePhrase.getFirstSqlWord()); | |
216 | + } | |
217 | + | |
218 | + /** | |
219 | + * 記号文字の集合 | |
220 | + */ | |
221 | + static final char[] SYMBOLS = { ',', '(', ')', '!', '+', '-', '*', '/', '=', '<', '>', ';' }; | |
222 | + | |
223 | + /** | |
224 | + * 現時点状態に対し、読み込み文字が次状態へ遷移すべきかを決定する。 | |
225 | + * 例えば、SQL句状態で、コメント開始文字(--や/*)を受け取ったら、コメント開始状態へ遷移する。 | |
226 | + */ | |
227 | + enum State { | |
228 | + PHRASE { | |
229 | + @Override | |
230 | + public State next(char[] dst) { | |
231 | + if (dst[0] == '/' && dst[1] == '*') | |
232 | + return SLASHCOMMENT_START; | |
233 | + if (dst[0] == '-' && dst[1] == '-') | |
234 | + return HIFUNCOMMENT_START; | |
235 | + if (dst[0] == '\'') | |
236 | + return APOST_START; | |
237 | + if (dst[0] == ' ' || dst[0] == '\t' || dst[0] == '\n') | |
238 | + return DELIMITER; | |
239 | + for (int i = 0; i < SYMBOLS.length; i++) { | |
240 | + if (dst[0] == SYMBOLS[i]) | |
241 | + return SYMBOL_CHAR; | |
242 | + } | |
243 | + return this; | |
244 | + } | |
245 | + }, | |
246 | + SYMBOL_CHAR { | |
247 | + @Override | |
248 | + public State next(char[] dst) { | |
249 | + return PHRASE.next(dst); | |
250 | + } | |
251 | + }, | |
252 | + | |
253 | + // APOST state | |
254 | + APOST_START { | |
255 | + @Override | |
256 | + public State next(char[] dst) { | |
257 | + if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] == '\'') | |
258 | + return APOST_ESCAPE; | |
259 | + if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] != '\'') | |
260 | + return APOST_END; | |
261 | + return APOST; | |
262 | + } | |
263 | + }, | |
264 | + APOST { | |
265 | + @Override | |
266 | + public State next(char[] dst) { | |
267 | + if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] == '\'') | |
268 | + return APOST_ESCAPE; | |
269 | + if ((dst[0] == '\'' || dst[0] == '\\') && dst[1] != '\'') | |
270 | + return APOST_END; | |
271 | + return this; | |
272 | + } | |
273 | + }, | |
274 | + APOST_ESCAPE { | |
275 | + @Override | |
276 | + public State next(char[] dst) { | |
277 | + return APOST; | |
278 | + } | |
279 | + }, | |
280 | + APOST_END { | |
281 | + @Override | |
282 | + public State next(char[] dst) { | |
283 | + return PHRASE.next(dst); | |
284 | + } | |
285 | + }, | |
286 | + | |
287 | + // SLASH COMMENT state | |
288 | + SLASHCOMMENT_START { | |
289 | + @Override | |
290 | + public State next(char[] dst) { | |
291 | + return SLASHCOMMENT; | |
292 | + } | |
293 | + }, | |
294 | + SLASHCOMMENT { | |
295 | + @Override | |
296 | + public State next(char[] dst) { | |
297 | + if (dst[0] == '*' && dst[1] == '/') | |
298 | + return SLASHCOMMENT_PREEND; | |
299 | + return this; | |
300 | + } | |
301 | + }, | |
302 | + SLASHCOMMENT_PREEND { | |
303 | + @Override | |
304 | + public State next(char[] dst) { | |
305 | + return COMMENT_END; | |
306 | + } | |
307 | + }, | |
308 | + | |
309 | + // HIFUN COMMENT state | |
310 | + HIFUNCOMMENT_START { | |
311 | + @Override | |
312 | + public State next(char[] dst) { | |
313 | + return HIFUNCOMMENT; | |
314 | + } | |
315 | + }, | |
316 | + HIFUNCOMMENT { | |
317 | + @Override | |
318 | + public State next(char[] dst) { | |
319 | + if (dst[0] == '\n') | |
320 | + return COMMENT_END; | |
321 | + return this; | |
322 | + } | |
323 | + }, | |
324 | + | |
325 | + // COMMENT state end (SLASH and HIFUN) | |
326 | + COMMENT_END { | |
327 | + @Override | |
328 | + public State next(char[] dst) { | |
329 | + return PHRASE.next(dst); | |
330 | + } | |
331 | + }, | |
332 | + | |
333 | + // DELIMITER state | |
334 | + DELIMITER { | |
335 | + @Override | |
336 | + public State next(char[] dst) { | |
337 | + return PHRASE.next(dst); | |
338 | + } | |
339 | + }, | |
340 | + | |
341 | + ; | |
342 | + | |
343 | + public abstract State next(char[] dst); | |
344 | + } | |
345 | + | |
346 | + /** | |
347 | + * 各字句要素の開始位置と終了位置を管理する | |
348 | + * | |
349 | + * @author sima | |
350 | + * | |
351 | + */ | |
352 | + abstract class Range { | |
353 | + /** | |
354 | + * 範囲指定が有効状態であるかを示す | |
355 | + */ | |
356 | + boolean valid = false; | |
357 | + | |
358 | + int beginPosition = Integer.MIN_VALUE; | |
359 | + int endPosition = Integer.MAX_VALUE; | |
360 | + | |
361 | + private String firstSqlWord = ""; | |
362 | + | |
363 | + /** | |
364 | + * 開始位置を設定し有効状態にする。但し、既に有効の場合は、開始位置を設定せずに復帰する。 | |
365 | + * | |
366 | + * @param beginPosition | |
367 | + */ | |
368 | + void begin(int beginPosition) { | |
369 | + if (valid) { | |
370 | + return; | |
371 | + } | |
372 | + this.beginPosition = beginPosition; | |
373 | + valid = true; | |
374 | + } | |
375 | + | |
376 | + /** | |
377 | + * 開始位置が設定されており、終了が未設定の場合、残りの領域を全て強制終了する。 | |
378 | + * | |
379 | + * @param sqlSentence | |
380 | + * @param listeners | |
381 | + */ | |
382 | + void finish() { | |
383 | + if (!valid) { | |
384 | + return; | |
385 | + } | |
386 | + end(sqlSentence.length() - 1); | |
387 | + } | |
388 | + | |
389 | + /** | |
390 | + * 終了位置を設定し無効状態にする。登録されているリスナーを呼び出す為に各実装クラスのメソッドを呼び出す。 | |
391 | + * 但し、無効状態の場合は、何もせずに復帰する。 | |
392 | + * | |
393 | + * @param sqlSentence | |
394 | + * @param listeners | |
395 | + * @param endPosition | |
396 | + */ | |
397 | + void end(int endPosition) { | |
398 | + if (!valid) { | |
399 | + return; | |
400 | + } | |
401 | + | |
402 | + this.endPosition = endPosition; | |
403 | + String word = sqlSentence.substring(beginPosition, endPosition + 1); | |
404 | + | |
405 | + for (SqlSentenceListener l : listenerList) { | |
406 | + fire(l, word); | |
407 | + } | |
408 | + valid = false; | |
409 | + if (getFirstSqlWord().equals("")) { | |
410 | + setFirstSqlWord(word); | |
411 | + } | |
412 | + } | |
413 | + | |
414 | + /** | |
415 | + * リスナーを呼びだす。継承先クラスで呼出処理は実装する。 | |
416 | + * | |
417 | + * @param l | |
418 | + * リスナー | |
419 | + * @param s | |
420 | + * 通知文字列 | |
421 | + */ | |
422 | + abstract void fire(SqlSentenceListener l, String sqlWord); | |
423 | + | |
424 | + @Override | |
425 | + public String toString() { | |
426 | + return beginPosition + ":" + endPosition; | |
427 | + } | |
428 | + | |
429 | + /** | |
430 | + * @param firstSqlWord | |
431 | + * セットする firstSqlWord | |
432 | + */ | |
433 | + void setFirstSqlWord(String firstSqlWord) { | |
434 | + this.firstSqlWord = firstSqlWord; | |
435 | + } | |
436 | + | |
437 | + /** | |
438 | + * @return firstSqlWord | |
439 | + */ | |
440 | + String getFirstSqlWord() { | |
441 | + return firstSqlWord.toUpperCase(); | |
442 | + } | |
443 | + } | |
444 | + | |
445 | + class RangeComment extends Range { | |
446 | + @Override | |
447 | + void fire(SqlSentenceListener l, String sqlWord) { | |
448 | + l.rangeComment(sqlWord, beginPosition, endPosition); | |
449 | + } | |
450 | + } | |
451 | + | |
452 | + class RangePhrase extends Range { | |
453 | + @Override | |
454 | + void fire(SqlSentenceListener l, String sqlWord) { | |
455 | + if (sqlWord.startsWith(":") || sqlWord.equals("?")) { | |
456 | + l.rangeInput(sqlWord, beginPosition, endPosition); | |
457 | + } else { | |
458 | + l.rangePhrase(sqlWord, beginPosition, endPosition); | |
459 | + } | |
460 | + } | |
461 | + } | |
462 | + | |
463 | + class RangeConstant extends Range { | |
464 | + @Override | |
465 | + void fire(SqlSentenceListener l, String sqlWord) { | |
466 | + l.rangeConstant(sqlWord, beginPosition, endPosition); | |
467 | + } | |
468 | + } | |
469 | + | |
470 | + class RangeDelimiter extends Range { | |
471 | + @Override | |
472 | + void fire(SqlSentenceListener l, String sqlWord) { | |
473 | + l.rangeDelimiter(sqlWord, beginPosition, endPosition); | |
474 | + } | |
475 | + } | |
476 | + | |
477 | + class RangeSymbol extends Range { | |
478 | + @Override | |
479 | + void fire(SqlSentenceListener l, String sqlWord) { | |
480 | + l.rangeSymbol(sqlWord, beginPosition, endPosition); | |
481 | + } | |
482 | + } | |
483 | + | |
484 | +} |
@@ -0,0 +1,40 @@ | ||
1 | +/* | |
2 | + * Copyright 2011 Kazuhiro Shimada | |
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 | + | |
17 | +package jdbcacsess2.sqlService.parse; | |
18 | + | |
19 | +import java.util.regex.Pattern; | |
20 | + | |
21 | +/** | |
22 | + * @author sima | |
23 | + * | |
24 | + */ | |
25 | +public interface SqlSentenceSparateListener { | |
26 | + /** | |
27 | + * SQL文セパレータ | |
28 | + * | |
29 | + * @param matchKeyword | |
30 | + * マッチ文字 | |
31 | + * @param beginPosition | |
32 | + * 開始位置 | |
33 | + * @param endPosition | |
34 | + * 終了位置 | |
35 | + * @param pattern | |
36 | + * マッチ時の正規表現 | |
37 | + */ | |
38 | + public void rangeSeparate(String matchKeyword, int beginPosition, int endPosition, Pattern pattern); | |
39 | + | |
40 | +} |