AnormでTypeDoesNotMatchを回避

最近、Playframework2/scalaで自宅用の家計簿なんかを作ってます。
DBアクセスにはPlay標準のAnormを使用していますが、その時困ったことです。

やりたかったのは実績の金額をある期間で分類ごとに合計するということで、分析関数のsum()を使用した列で値を取得していました。

SQL

SELECT
  distinct sum(amount) over (partiton by category_id) as total_amount
FROM
  actual
WHERE
  actual_date >= {startDate} AND actual_date <= {endDate}

パーサ

val simple = {
  get[Long]("total_amount") map {
      case totalAmount => (totalAmount)
    }
}

コンパイルは通ったのですが、実行時に

TypeDoesNotMatch(Cannot convert 67300:class java.math.BigDecimal to Long

という例外が発生しました。
パーサにはget[Long]を使用していたのですが、ならばということでget[java.math.BigDecimal]に変えてみたのですが、今度は

TypeDoesNotMatch(Cannot convert 0:class java.lang.Integer to BigDecimal

となってしまいました。

どうやら、行ごとの値(この場合0や67300)によって 列の型が異なるようです。
うーんこれは仕様?JDBCの固有の特性?よくわかりません。
ちなみにDBMSPostgreSQLです。

回避方法は、AnormのソースからLong型の列のパーサをコピペしてきてそこへBigDecimalのcaseを追加してやりました。
そしてこれを上記のパーサの前に書いておきます。これでIntでもLongでもBigDecimalでも無事get[Long]で取得できるようになりました。

implicit def rowToLong: Column[Long] = Column.nonNull { (value, meta) =>
    val MetaDataItem(qualified, nullable, clazz) = meta
    value match {
      case int: Int => Right(int: Long)
      case long: Long => Right(long)
      case bigDecimal: java.math.BigDecimal => Right(bigDecimal.longValue)  // 追加
      case _ => Left(TypeDoesNotMatch("Cannot convert " + value + ":" + value.asInstanceOf[AnyRef].getClass + " to Long for column " + qualified))
    }
  }

もっと良い方法ご存知のかたは教えて下さい。

Android SDK の4.0(API 14)未満のソースコードを取得する


EclipseSDKのソースを開きたかったのですが、Android SDKのsoucesディレクトリにAPI 14以前のディレクトリがありませんでした。
Android SDK Managerから確認すると4.0(API 14)未満のダウンロード出来ないようです。
f:id:khey83:20121202072003g:plain
なので、ソースをダウンロードすることにします。
http://source.android.com/source/downloading.html:こちらのサイトの手順にしたがってダウンロードします。
まず、Repoツールをインストールします。

# ~/local以下に自分用のツールを入れているため~/local/binにインストールします
# 予めPATHに~/local/binにを追加しておきます
# $ PATH=~/local/bin:$PATH
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/local/bin/repo
$ chmod a+x ~/local/bin/repo

そして、ソースをダウンロードします。

# Android SDKホームディレクトリにrepo_workspaceディレクトリを新たに作成しました
$ mkdir <Android SDK Home>/repo_workspace
$ cd <Android SDK Home>/repo_workspace
# Froyoのソースが欲しかったので、ブランチにはandroid-2.2.3_r2.1を指定しました
# (適当なブランチ名で実行すると間違っていた場合指定できるブランチ名のリストが表示されるので、それで正式名称を見れました)
$ repo init -u https://android.googlesource.com/platform/manifest -b android-2.2.3_r2.1
# 実際にソースをダウンロードします
$ repo sync
# (ダウンロード完了するまでに15分ぐらいかかり、容量は7GB超でした)

SDKソースコードはframeworks/baseディレクトリ以下の各ディレクトリ配下のjavaディレクトリ配下にあります。

$ cd frameworks/base
# mergeディレクトリを作ってその中に集めます
$ mkdir merge
$ cp -r */java merge
# 余計なファイルを削除しておきます
$ cd merge/java
$ rm Android.mk jarjar-rules.txt overview.html

Android SDKソースコードディレクトリにコピーしておきます。

# Froyo(API 8)のソースなのでandroid-8ディレクトリにします
$ cp -r . ~/local/android-sdk-macosx/sources/android-8

これでEclipseなどでSDKのソースを見れるようになります。

MacBook で Goole Maps をタッチパッド(トラックパッド)で操作したい

MacBookにしてからBetterTouchToolを入れて快適に過ごしていたのですが、
ブラウザでGoogle Mapsを操作するときに2指スワイプがズームイン/アウトになってしまい非常に不自然で不便をしていました。

そこで探していると、Chromeの拡張でChrome Web Store - ScrollMapsなるものがありました!(試していませんが、Safariの拡張もあるようです)
この拡張でGoogle Mapsでの2指スワイプが直感的な操作になります。

オプション画面はこんなかんじです。
f:id:khey83:20121119053402g:plain
Embeded maps require activationのチェックは外しておくとマップをクリックしなくてもマップの上にポインタを持っていくだけでこの拡張が有効になるので良い感じです。

設定ファイル(dotfiles)をGitHubで管理する

~/.zshrcや./emacs.d等の各アプリケーションの設定ファイルをGitHub上で管理すると他のPC(仕事用)などでも同じ設定を共有できてるということでやってみました。

基本的なアイデアとしては、以下のようになります。

  1. ホームディレクトリ直下にdotfilesというフォルダを作りそこに各アプリケーションの設定ファイルを配置し、ホームディレクトリにはそれらへのシンボリックリンクを作成します。
  2. dotfilesディレクトリをGitHub上にpushし共有します。
  3. 他のPCではdotfilesディレクトリをGitHub上からcloneし、そのディレクトリから1と同様にシンボリックリンクをホームディレクトリに作成することで同じ設定ファイルを共有します。

それでは、手順を追っていきます。

Gitのインストール

GitのインストールはHomebrewでやっておきます。

$ brew install git

Gitの設定は以下の2つをやっておきます。

$ git config --global user.name [ユーザ名]
$ git config --global user.email [Eメール]

GitHubの準備

  1. https://github.comでアカウントを作成します。
  2. Generating SSH Keys · github:helpの手順に従ってSSHの公開鍵をGitHubに登録します。
  3. 個人ページのトップ画面からリポジトリを作成します。僕は「dotfiles」という名前のリポジトリにしました。

Gitリポジトリの作成とGitHub上へのPush

以下コマンドで行います。

$ mkdir ~/dotfiles
(ホームディレクトリ直下にdotfilesディレクトリを作成)
$ cd ~/dotfiles
$ git init
(Gitリポジトリを作成)
$ mv ~/.zshenv .
$ ln -s .zshenv ~/.zshenv
(共有したい設定ファイルをdotfilesディレクトリに移動し、シンボリックリンクをホームディレクトリ直下に作成する)
$ git add .zshenv
$ git commit -m 'zsh setting file commit'
(共有したい設定ファイルをコミット)
$ git remote add orign git@githob.com:[GitHub上のユーザ名]/[GitHub上のリポジトリ名(dotfiles)].git
$ git push origin master
(コミットした設定ファイルをGitHub上にPush)

共有する設定ファイル

僕はとりあえずzshの設定ファイルを共有しましたが、シェルの設定ファイルを共有する人が多いみたいです。
あとはvimEmacs等のエディタの設定ファイルにも使えます。
注意点としてはGitHubのリポジトリは無料のプランだとすべて公開リポジトリなので.sshフォルダなど公開してはまずいファイルが含まれているものは共有しないように注意しましょう。

zshのインストール

zshは前から高機能だということで聞いていたですが、なかなか手が出せずにいたのでこれを機に使い込んでみようかと思っています。

先日インストールしたHomebrewを使ってで普通に brew install zsh としてインストールしましたが、インストールの最後で以下のようなコメントが出たので、

To use this build of Zsh as your login shell, add it to /etc/shells.

If you have administrator privileges, you must fix an Apple miss
configuration in Mac OS X 10.7 Lion by renaming /etc/zshenv to
/etc/zprofile, or Zsh will have the wrong PATH when executed
non-interactively by scripts.

Alternatively, install Zsh with /etc disabled:

  brew install --disable-etcdir zsh

一旦アンイストールしてから以下のコマンドでインストールし直しました。

$ brew install --disable-etcdir zsh

こちらを参考にさせていただきました。

あとはzshを通常使うシェルに登録します。

$ sudo emacs /etc/shells
(/usr/local/bin/zshを追加)
$ chsh
(/bin/bashを/usr/local/bin/zshに修正)

追記(2012/11/19):
zshはいろいろな機能があるそうなのですが、今はとりあえずoh-my-zshを入れて使っています。

$ cd ~
$ git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
$ cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

Homebrewのインストール

f:id:khey83:20121018152713j:image:medium
MacでのパッケージマネージャはMacPortsが標準ですが、今はHomebrewというのが人気のようです。
HomebrewはOSXのライブラリも考慮してパッケージ管理が行えるということで人気らしいです。
MacPortsは完全独立で考慮してくれないらしいです。
あと、/usr/local/配下にインストールパッケージを納めていくらしくsudoもいらないのでパスワード入力が省けて良い感じみたいです。

Homebrewのインストール前にDownloads for Apple DevelopersからXcodeの最新版をダウンロードしてインストールしておきます。
Xcodeを起動してFile>PreferenceでPreference画面を開きDownloadsタブでCommand Line Toolsをインストールしておきます。
ちなみにMacではPreferenceはFile>Preferenceが普通みたいですね。あとショートカットもCommand+,というのが共通しているみたいです。
肝心のHomebrewのインストールは以下のコマンド一発で完了してしまいます。

$ ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"

とりあえずコマンドは以下のものを覚えておきました。

$ brew install [パッケージ名]
(インストール)
$ brew unistall [パッケージ名]
(アンインストール)
$ brew info [パッケージ名]
(パッケージ情報の表示)