Select From Git

via
JDBC

About Me

  • 山名 洋平

  • キャスレーコンサルティング

  • @vertical_blank

  • github.com/yohei224

gitql


$ gitql 'select * from branches'
|---------------------------------------------------------------------------------------|
| Name           | Full_name                 | Hash                                     |
|---------------------------------------------------------------------------------------|
| master         | refs/heads/master         | d4d223d31992af2a92adc2e7b4ca63c383380c4c |
|---------------------------------------------------------------------------------------|
| polyglot-maven | refs/heads/polyglot-maven | 925cfbfe29823665f2067dbe37cb487a2b4f9b3e |
|---------------------------------------------------------------------------------------|

https://github.com/cloudson/gitql

Javaでもできそう

Libraries

  • JGit

  • JSQLParser

JGit

GitのPureJava実装

JSQLParser

String sql = "SELECT a,b,c FROM PIYO WHERE ID = 9 ORDER BY HOGE DESC, FUGA";
Select selectStatement = (Select) CCJSqlParserUtil.parse(sql);
PlainSelect select = (PlainSelect) selectStatement.getSelectBody();

select.getFromItem().toString();                              // => PIYO

List<SelectItem> selectItems = select.getSelectItems();
foreach(SelectItem selectItem: selectItems){
    selectItem.toString();                                    // => a,b,c
}

// VisitorPattern 各条件要素について、型や演算子に応じたvisitがコールバックされる
Expression where = select.getWhere();
where.visit(ExpressionVisitor);

List<OrderByElement> orderByElements = select.getOrderByElements();
foreach(OrderByElement orderByElement: orderByElements){
    orderByElement.getExpression().toString();                // => HOGE, FUGA
    orderByElement.getExpression().isAsc();                   // => false, true
}

単純なselectならこんな感じ

JDBC interface

java.sql.

  • Driver

  • Connection

  • Statement

  • DataBaseMetaData

  • ResultSet

  • ResultSetMetaData

Driver

// これを呼ぶか、META-INF/services/java.sql.Driverに
// このクラスの完全修飾名を書いておく必要がある
Class.forName("jgitdbc.Driver");

DriverManager.getConnection("jdbc:jgitql:....");
// static初期化子の中で自分自身のインスタンスをregisterしておく
static {
  try {
    register();
  } catch (SQLException e) {
    throw new ExceptionInInitializerError(e);
  }
}

public static void register() throws SQLException {
  if (isRegistered()) {
    ...
  }
  Driver registeredDriver = new Driver();
  DriverManager.registerDriver(registeredDriver);
  Driver.registeredDriver = registeredDriver;
}

Demo

JDBCなCLI SQL Client

SQL解釈, 実行するのって大変

  • SELECTで指定しないカラムをWHERE, ORDERに入れると落ちる → 絞る前にフィルタ、ソート
  • 基本的にカラム番号は1始まりなのを忘れてArrayIndexOutOfBoundsException発生
  • API側でintで受けるような場所 ResultSet.getInt(idx)
    Nullが渡りぬるぽ
  • Connection.getMetaData().getTables()/getColumns()
    で返すべきカラムは決まりがあるが
    型で縛られているわけではない(
    JavaDocには書いてある) → 実装し忘れ

宣伝

ScalaでGitバックエンドな

Qiita風アプリ作ってます

https://github.com/yohei224/turqey

でも今回のJDBCドライバ使ってません...

ご静聴

ありがとうございました

deck

By yohei yamana