SQLを解析することで、SQLを動的に解析して単体試験仕様書の作成を自動化したい
そのためには次の項目を自動抽出したい。
Oracleのプレースホルダー
さらにいうと、
http://www.antlr.org/grammar/list
よくわからない状態で、ためしにEclipseのビルドパスに外部Jarとしてぶっこんで、
http://www.antlr.org/wiki/display/ANTLR3/ANTLR+Cheat+Sheet
をためしてみたが、TLexerとTParserが見つからない、どうやら事前に生成するようだ。
expr.gで下記の内容を保存してみる。
class ExprParser extends Parser; expr: mexpr ((PLUS|MINUS) mexpr)* ; mexpr: atom (STAR atom)* ; atom: INT | LPAREN expr RPAREN ;
class ExprLexer extends Lexer; options { k=2; // needed for newline junk charVocabulary='\u0000'..'\u007F'; // allow ascii } LPAREN: '(' ; RPAREN: ')' ; PLUS : '+' ; MINUS : '-' ; STAR : '*' ; INT : ('0'..'9')+ ; WS : ( ' ' | '\r' '\n' | '\n' | '\t' ) {$setType(Token.SKIP);} ;
次のようにコマンドラインで実行する
java -classpath antlr-3.2.jar antlr.Tool expr.g
なにやらファイルが生成された
http://www.antlr.org/grammar/1174072667394/PLSQLGrammar.g
上記ファイルをダウンロードして下記のように打ち込むと
java -classpath antlr-3.2.jar antlr.Tool PLSQLGrammar.g
クラスファイルが出来上がる。
で、下記のクラスを要求している
そのファイルは下記よりダウンロード可である。
http://www.antlr.org/grammar/1174072667394/SoftwareMetrics.java
でこのSoftwareMetrics?はいろいろ摩訶不思議な設定が必要だが、その方法は下記よりダウンロード可能
http://www.antlr.org/grammar/1174072667394/PLSQLMain.java
http://antlreclipse.sourceforge.net/
http://www.limy.org/program/java/antlr/step1.html
http://openjdk.java.net/projects/compiler-grammar/antlrworks/
http://openjdk.java.net/projects/compiler-grammar/antlrworks/
Apache Derby
はApacheのDBのサブプロジェクトでしてそのApache Derbyにパーサがあるらしい
.native() メソッドを見るといいようだ。
http://jsqlparser.sourceforge.net/
SQLを解析してJavaクラスの階層構造に変換するらしい
ダウンロードしてきたjarのパスをzipに変換して解凍し、 そのなかからlibフォルダにjarがあるので、そいつをeclipseのビルドパスに外部jarとして取り込ませる。
サイトのサンプルがちょっと手直しが必要だったので直して、日本語訳しておきます。
TablesNamesFinder?のStringValue?はEclipseの自動保管を使うとjava.langの方をつかうので、
import net.sf.jsqlparser.expression.StringValue;
としておきましょう
JoinVisitor?(だっけか?)は削除しておきます。
CCJSqlParserManager pm = new CCJSqlParserManager(); /* * Oracleのプレースホルダーは対応してないので、''で括るなどしましょう * :AAA -> ':AAA' * Oracleの外部結合である(+)も対応していないので、削っておきましょう * (+) -> 削除 */ String sql = "SELECT * FROM MY_TABLE1, MY_TABLE2, (SELECT * FROM MY_TABLE3) LEFT OUTER JOIN MY_TABLE4 "+ " WHERE ID = (SELECT MAX(ID) FROM MY_TABLE5) AND ID2 IN (SELECT * FROM MY_TABLE6)" ; net.sf.jsqlparser.statement.Statement statement = pm.parse(new StringReader(sql)); /* 対象のSQL文字列が何を行うか(たとえばSELECTなのかINSERTなのか...)に応じて、 StatementVisitorをimplementsで実装したクラスをつかってください。 とりあえずここでは例としてSELECT用のselectStatementをつかっています。 */ if (statement instanceof Select) { Select selectStatement = (Select) statement; TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); List tableList = tablesNamesFinder.getTableList(selectStatement); for (Iterator iter = tableList.iterator(); iter.hasNext();) { System.out.println(iter.next()); } }
http://www.gibello.com/code/zql/
Javaで書かれたSQLのParser
http://byaccj.sourceforge.net/
YACCと互換性あるそうな。
http://www2.cs.tum.edu/projects/cup/
JavaのParser生成ライブラリー
JFlexはこちら
YACCのような位置づけである。
YACCとの違いは外部ファイルを必要としないとか。