Skip to content

SquerylでPostgreSQLのgeometry関連関数を使う

SquerylでPostgreSQLのgeometry関連関数を使う published on SquerylでPostgreSQLのgeometry関連関数を使う への1件のコメント

以前別ブログで、Squerylで最初からは用意されていない集計関数(median)を実装する、というエントリを書いた。今回はそれと似た内容で、PostgreSQLの位置情報の関数をSquerylで使えるようにしてみる。

Squeryl 0.9.5-6

距離を調べるSQL

今回使いたいのは、2点間の距離を調べる <-> という関数。例えば、以下のクエリーのように、ある位置(36.726637,139.526557)から3000m以内にある点のうち、距離が近い順に30件取得したいとする。これをSquerylを使って実現したい。

SELECT p.*, (p.latlng <-> POINT(36.726637,139.526557)) * 111000 as l
FROM place p
WHERE (p.latlng <-> POINT(36.726637,139.526557)) < 3000.0 / 111000.0
ORDER BY p.latlng <-> POINT(36.726637,139.526557)
LIMIT 30

Continue reading SquerylでPostgreSQLのgeometry関連関数を使う

FabricでPlay! frameworkアプリのデプロイを自動化してみた

FabricでPlay! frameworkアプリのデプロイを自動化してみた published on FabricでPlay! frameworkアプリのデプロイを自動化してみた へのコメントはまだありません

随分前から、勉強がてら個人でちょこちょこwebサイト作ってる。デプロイはjarファイルのコピーだけとは言え、毎回手動でdeployとサービス再起動をするのはさすがに面倒になってきたので、デプロイを自動化するツールを導入する事にした。

環境等

  • Play! framework 2.2
  • web(app)、DB、バッチでサーバーが分かれている
  • デプロイ先はいずれもLinux
  • ローカル開発環境はOS X Mavericks (10.9)
  • Fabric 1.8.1を使用

Continue reading FabricでPlay! frameworkアプリのデプロイを自動化してみた

logrotateでcopytruncateしてもサイズが大きいまま

logrotateでcopytruncateしてもサイズが大きいまま published on logrotateでcopytruncateしてもサイズが大きいまま へのコメントはまだありません

logrotateには色んなオプションがある。(logrotateが何をするツールかはググって下さい)。そのうちの1つに copytruncate というものがある。動作としては以下の通り。

  • 対象ログがa.logだとすると、それを a.log.0 あるいは a.log-yyyymmddにコピー
  • a.logをtruncate (内部的には cp /dev/null /path/to/a.log みたいな処理)

ログ・ファイルのサイズが大きいままになる問題

ログファイル名は a.log とする。logrotate の設定で copytruncate になっているとすると、ローテートの際に、前述の通り a.log が a.log.0 にコピーされる。a.log が 100KBだとすると、a.log.0 は100KBで、その後 a.log は truncate されて 0バイトになるはず。

だが、以下の様な現象が起こる場合がある。

  • a.log が a.log-0 にコピーされる (a.log-0 のサイズは100KB)。
  • a.log が truncate される。
  • a.log のサイズが 100KBに戻る。

a.log の最初の100KBはNULL byte(\0)で埋められ、その後からログが書き込まれる。

想像がつくと思うけど、ログファイルに書き込むプロセスが保持しているファイルポインターが100KBの位置のままの場合、a.log が truncate されてサイズが0になっても、その後のログ書き込みで100KBの位置に書き込まれ、結果として最初の100KBがNULLで埋められる。

原因、解決方法

ログファイルを開く際に O_APPEND オプションが付いていない場合にこうした現象が起こる。シェル(sh や bash)の場合、

$ command > a.log

の場合、O_APPEND 無しでファイルが開かれるので、上のような現象が発生する。それに対して、以下の場合には問題が発生しない。

$ command >> a.log

ということで、シェルスクリプトからログファイルにログを書き込む際に > でリダイレクトをしている場合、logrotate の copytruncate で上のような問題が発生するので、 >> を使うようにすると良い。

なんで > と >> で挙動が違うかは、歴史的背景らしい。

参考

ググって見つけたこのページこのページが参考になった。

Play! frameworkのテンプレートでパターンマッチを使う方法

Play! frameworkのテンプレートでパターンマッチを使う方法 published on Play! frameworkのテンプレートでパターンマッチを使う方法 へのコメントはまだありません

Play!のテンプレートは型安全だし、中でScalaが使えるのでそこそこ便利なんだけど、スペースの有無でコンパイルが通らなかったりとか、色々面倒な部分も。

特にパターンマッチを使いたかったのに、なかなかうまく行かなくて色々試行錯誤した。

結論から言うと、以下のように改行を入れるとOKだった(公式サイトのTemplateのuse caseのページより引用)。

@level match {

  case "success" => {
    <p class="success">
      @body("green")
    </p>
  }

  case "warning" => {
    <p class="warning">
      @body("orange")
    </p>
  }

  case "error" => {
    <p class="error">
      @body("red")
    </p>
  }

}

環境:Play! framework 2.2

Play! frameworkでモバイルサイトを作る

Play! frameworkでモバイルサイトを作る published on Play! frameworkでモバイルサイトを作る へのコメントはまだありません

冬休みの宿題ということで、前からぼちぼち作っているサイトのモバイル版を作ろうと思った。モバイル向けの部分はjQuery Mobileを使うことにした(これに関しては別エントリーで)。

環境

  • Play! framework 2.2

(主に)3種類の選択肢

desktopとmobile (smart phone)の両方に対応したサイトを作る場合、主に以下の3通りがある。

  1. 同じURL。User-Agentで判断して異なるHTML、CSS、JavaScriptを返す。
  2. 異なるURL。(www.example.com と m.example.com など)
  3. 同じURL。レスポンシブデザイン。

(3は今の自分がやるには面倒なのでとりあえず除外するとして)、どれがいいんだろう?と思ってちょっとググってみたところ、Googleのこんなページが見つかった。

正直、ユーザーにとっては同じURLだろうと異なるURLだろうとそんな気にしないだろうから(自動的にリダイレクトしてくれれば)、SEOという観点は重要かなと思った。

で、結論として1番の同じURL、異なるコンテンツ、という方式を選ぶことにした。

Continue reading Play! frameworkでモバイルサイトを作る

Mahout 0.8でクラスタリング

Mahout 0.8でクラスタリング published on Mahout 0.8でクラスタリング へのコメントはまだありません

こないだ「Mahout 0.8でレコメンデーションエンジンを作る」という、Mahoutの簡単なエントリーを書いたけど、今回はクラスタリングの話。

今回も、Mahoutの基本知識は知っていることを前提として書く。Mahout in Actionが入門向けで良いかと(ページ末尾参照)。

Continue reading Mahout 0.8でクラスタリング

OSXでthe trustAnchors parameter must be non-emptyって出る

OSXでthe trustAnchors parameter must be non-emptyって出る published on OSXでthe trustAnchors parameter must be non-emptyって出る へのコメントはまだありません

しばらく放置してたプログラムの開発を再開した。開発環境はMBP。OSX Mavericks。

で、起動したら、ある箇所で以下のようなExceptionが発生。

java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

ぐぐってみたら、JREの証明書がなんたらかんたら、と。詳細は省略するけど、Javaをインストールすれば(orし直せば)OK。MavericksではJavaがインストールされないの?

  • Java 6なら、Appleのサイトからダウンロード
  • Java 7なら、Oracleのサイトからダウンロード(JRE, JDK)

自分用メモ

スタックトレース

[error] application - [securesocial] error trying to get an access token for provider facebook
java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Handshaker.java:1012) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:485) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:753) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:721) ~[na:1.6]
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:607) ~[na:1.6]
        at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1225) ~[netty.jar:na]
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at sun.security.validator.PKIXValidator.(PKIXValidator.java:57) ~[na:1.6.0_32]
        at sun.security.validator.Validator.getInstance(Validator.java:161) ~[na:1.6.0_32]
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:108) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:204) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185) ~[na:1.6]
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:183) ~[na:1.6.0_32]
        at java.security.cert.PKIXParameters.(PKIXParameters.java:103) ~[na:1.6.0_32]
        at java.security.cert.PKIXBuilderParameters.(PKIXBuilderParameters.java:87) ~[na:1.6.0_32]
        at sun.security.validator.PKIXValidator.(PKIXValidator.java:55) ~[na:1.6.0_32]
        at sun.security.validator.Validator.getInstance(Validator.java:161) ~[na:1.6.0_32]
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:108) ~[na:1.6]
[error] application - Unable to log user in. An exception was thrown
securesocial.core.AuthenticationException: null
        at securesocial.core.OAuth2Provider.securesocial$core$OAuth2Provider$$getAccessToken(OAuth2Provider.scala:67) ~[securesocial_2.10-2.1.2.jar:2.1.2]
        at securesocial.core.OAuth2Provider$$anonfun$3$$anonfun$apply$5$$anonfun$apply$8.apply(OAuth2Provider.scala:106) ~[securesocial_2.10-2.1.2.jar:2.1.2]
        at securesocial.core.OAuth2Provider$$anonfun$3$$anonfun$apply$5$$anonfun$apply$8.apply(OAuth2Provider.scala:104) ~[securesocial_2.10-2.1.2.jar:2.1.2]
        at scala.Option$WithFilter.map(Option.scala:206) ~[scala-library-2.10.3.jar:na]
        at securesocial.core.OAuth2Provider$$anonfun$3$$anonfun$apply$5.apply(OAuth2Provider.scala:104) ~[securesocial_2.10-2.1.2.jar:2.1.2]
        at securesocial.core.OAuth2Provider$$anonfun$3$$anonfun$apply$5.apply(OAuth2Provider.scala:103) ~[securesocial_2.10-2.1.2.jar:2.1.2]

Play! framework 2.1 → 2.2に上げた

Play! framework 2.1 → 2.2に上げた published on Play! framework 2.1 → 2.2に上げた への1件のコメント

正月休みを利用して、Play! framework 2.1のプロジェクトを2.2にした。あ、皆様あけましておめでとうございます。

結論から言っちゃうと、Play 2.2 Migration Guideに書いてある情報で大体網羅されていた。

Play自体のアップグレード

Migration Guide通り、Build.scalaとか修正すればOK。最新バージョンは2.2.1なので、ドキュメントに2.2.0って書いてある所は、2.2.1と置き換えて読めばOK。

サードパーティライブラリのアップグレード

Playのプラグインとかライブラリでは、Play 2.1.xの人はバージョンMを、Play 2.2.xの人はバージョンNを使ってくれ、っていうパターンのものが結構ある。

そういったライブラリとかのバージョンを正しいものに変更せずにビルドしようとすると、以下の様なエラーが出た。

[error] Modules were resolved with conflicting cross-version suffixes in {file:/Users/kazu/Documents/workspace/projectfoo/}projectfoo:
[error]    org.scala-stm:scala-stm _2.10, _2.10.0
[trace] Stack trace suppressed: run last projectfoo/*:update for the full output.
[error] (projectfoo/*:update) Conflicting cross-version suffixes in: org.scala-stm:scala-stm
[error] Total time: 0 s, completed Jan 1, 2014 12:31:37 AM

個人的に使っていて、バージョン変更する必要があったのはこの辺。

ソースの変更

自分が必要となったところだけ記載。

Result -> SimpleResult

これもMigration Guideに書いてあるけど、play.api.mvc.Resultはdeprecatedになった。

play2-auth関連のコードも修正が必要。具体的にはAuthConfigImpleの各メソッドのシグニチャーを変更すればOK。

Jackson

パッケージ名が変わってる。org.codehaus.jackson → com.fasterxml.jackson

その他(追記)

evolutionsが再実行されそうに

開発環境で起動したら、evolutionsでかなり昔まで戻ってから再実行されそうになった。例えば、現在の最新が50.sqlだとして、20.sqlまでDownが実行され、その後再度20〜50.sqlのUpが実行されそうになった。

原因は、20.sql を適用した後に、20.sql をいじった為だと思う。ただ、Play 2.1の時には、適用済みの古いスクリプトを修正してもそこまで巻き戻らなかったんだけど、Play 2.2で若干仕組みが変わったらしい。詳しくはこちらを参照。

対策として、新しいまっさらなDBを作ってそこでevolutionsを実行し、その後play_evolutionsテーブルから必要なエントリーを元のDBに移し替えること。

specs2関連

以前は以下のようなのがOKだったが、

listOfStrings must contain("A", "B") //A, Bが両方含まれていないとダメ
listOfStrings must not contain("C", "D") // C, Dのどっちかでも含まれていたらダメ

以下のように書き換えないとダメだった。specs2のバージョンは一緒なのに何でだろう。Scalaのバージョンが変わったからかな?

listOfStrings must contain(allOf("A", "B")) //A, Bが両方含まれていないとダメ
listOfStrings must not contain("C")
listOfStrings must not contain("D")

最後に

Play 2.0 → 2.1の時よりは楽だった気がする。あの時はJson周りとか結構変更になったし。

現状、コンパイル通っただけで、まだあんまりテストしてないので、何かあれば追記予定。