2011年2月16日水曜日

Tapsについて追記

前回 tapsの導入について書きましたが、実際にデータをプッシュしてみると2点ほど
エラーが出たので、一応回避手段をメモしておきます。

(1) データ転送中に何度か「MySQL server has gone away」のエラーがでる。

ISSUES におんなじ現象にぶち当たってる人がいていくつか回避策が載っていました。
私の場合は「/etc/my.cnf」を編集して「max_allowed_packet」の値を大きくする方法で
とりあえずエラーは出なくなりました。

(2) データの行数が多いテーブルを移行している途中で
「can't add a new key into hash during iteration」のエラーが発生して処理が中断される。

→どうやらメモリが足りなかった模様です。。VMWareで検証していたので、
割り当てメモリを1GB増やしたらエラーがでなくなりました。

2011年2月15日火曜日

CentOS5.5でTapsを動かす

Taps というツールを使ってPostgreSQLのデータをMySQLに移行しようとしたんですが、CentOS5.5へのRubyやらGemやらのインストールで割と手こずったのでメモ書きを。

まずはgemのインストールで使うライブラリとcheckinstallをyumでインストールします。

yum install mysql-devel postgresql-devel sqlite-devel checkinstall

Rubyは2011年2月現在yumでインストールできる1.8.5では
うまく動かなかったので公式サイトからファイル落としてきてインストールします。

wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p136.tar.gz
tar zxvf ruby-1.9.2-p136.tar.gz
cd ruby-1.9.2-p136
./configure --prefix=/usr
make
/usr/sbin/checkinstall --fstrans=no
### 対話でRPMを選択 ###

rpm -Uvh /usr/src/redhat/RPMS/i386/ruby-1.9.2-p136-1.i386.rpm

各種gemをインストールします。

gem update --system
gem install json --version '=1.5.1'
gem install sequel --version '=3.20.0'
gem install rack --version '=1.2.1'
gem install sqlite3-ruby --version '=1.2.5' -- --with-sqlite3-lib="/usr/lib/sqlite"
gem install pg --version '=0.10.1' -- --with-pg-lib="/usr/lib/pgsql"
gem install mysql --version '= 2.8.1' -- --with-mysql-lib=/usr/lib/mysql
gem install sinatra --version '=1.1.2'
gem install rest-client --version '=1.6.1'

TapsのGithub からバージョン「0.3.15」のファイルを落としてきて/usr/local/tapsに展開します。
そのまま起動してもgemのファイルが読み込めないエラーが出る場合は下記のファイルを書き換えます。

/usr/local/taps/lib/taps/cli.rb
一行目に下記を追加

require 'rubygems'

移行先のデータベース情報でtapsサーバー起動します。
/usr/local/taps/bin/taps server mysql://mysqluser:mysqlpassword@mysqlhost/databaseto?encoding=utf8 httpuser httppassword &

移行元のデータベースを指定して移行元からサーバーへデータをPushします。
/usr/local/taps/bin/taps push postgres://pguser:pgpassword@pghost/databasefrom http://httpuser:httppassword@localhost:5000

とりあえず動くところまで・・・。
データの検証とかは別途必要になります。

2011年2月12日土曜日

Slim3 + Scalaをはじめてみる

仕事とは関係なく純粋な趣味でScalaをお勉強してみたいと思います。
Scalaを選んだ理由は特にないのですが、強いてあげるなら
  1. Javaのクラスをつかえるからとりあえず動くものをつくってためしやすそう
  2. 学生時代にMLを習って関数型言語に何となく苦手意識をもっていたので
  3. NetBeansのプラグインをつかえばけっこう補完とかもきくみたい
といったところでしょうか。

ものを作りながら勉強するほうが楽しいので、
Google App Engine/JavaとSlim3をつかって
イージーなWebアプリでもつくりながらまったりやっていきたいと思います。

そんなわけでまずは環境構築から。
開発環境はこんな感じで
  • MacOSX - 10.6.6
  • Netbeans - 6.9.1
  • Scala - 2.8.0
  • AppEngine Java SDK - 1.4.0
  • Slim3 - 1.0.6
まずはMavenで下記のコマンドを実行します。

cd ~/workspace
mvn archetype:generate -DarchetypeCatalog=http://slim3.googlecode.com/svn/trunk/repository

で、最初にベースのarchetypeをきかれますのでとりあえず1を選択します。
あとはパッケージ名とプロジェクト名をお好みで入力します。

最後の確認で「y」を押すとプロジェクト名と同じディレクトリが
カレントフォルダ直下に出来上がります。

あとはpom.xmlにちまちまとScala用の設定を追記していく感じです。

<properties>タグに追記
    <!-- Scala -->
    <scala.version>2.8.0</scala.version>
    <!-- Common plugin settings -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>${project.build.sourceEncoding}</project.reporting.outputEncoding>

<repositories>タグに追記
    <!-- Scala -->
    <repository>
      <id>scala-tools.releases</id>
      <name>Scala-Tools Dependencies Repository for Releases</name>
      <url>http://scala-tools.org/repo-releases</url>
    </repository>

<pluginRepository>タグに追記
    <!-- Scala -->
    <pluginRepository>
      <id>scala-tools.releases</id>
      <name>Scala-Tools Plugins Repository for Releases</name>
      <url>http://scala-tools.org/repo-releases</url>
    </pluginRepository>

<dependencies>タグに追記
    <!-- Scala -->
    <!-- for Console -->
    <dependency>
      <groupId>org.scala-lang</groupId>
      <artifactId>scala-compiler</artifactId>
      <version>${scala.version}</version>
    </dependency>

<build><plugins>タグに追記
      <!-- Scala -->
      <plugin>
        <groupId>org.scala-tools</groupId>
        <artifactId>maven-scala-plugin</artifactId>
        <version>2.14.3</version>
        <configuration>
          <charset>${project.build.sourceEncoding}</charset>
          <jvmArgs>
            <jvmArg>-Xmx1024m</jvmArg>
            <jvmArg>-DpackageLinkDefs=file://${project.build.directory}/packageLinkDefs.properties</jvmArg>
          </jvmArgs>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>testCompile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.4.2</version>
        <executions>
          <execution>
            <id>default-copy-resources</id>
            <phase>process-resources</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <overwrite>true</overwrite>
              <outputDirectory>${project.build.directory}</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.basedir}/src</directory>
                  <includes>
                    <include>packageLinkDefs.properties</include>
                  </includes>
                  <filtering>true</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>

だいぶ長くなってしまいました・・・不要な部分もあるかと思うので
おいおい調整していきます。

以上でsrc/main/scala以下にscalaのソースをおいて
コンパイルされるようになるはずです。

試しにIndexControllerをScalaで書いてみましょう。
quickstartのarctypeで生成されるIndexController.javaを
削除して、src/main/scala/の下にScalaのパッケージを作成して、
下記のような形でIndexController.scalaを書いてみます。

package com.sample.controller;

import java.util.Date;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.datastore.Datastore;

import com.sample.meta.Slim3ModelMeta;
import com.sample.model.Slim3Model;

import scala.collection.JavaConversions._

class IndexController extends Controller {
  @throws(classOf[Exception])
  override protected def run():Navigation = {
    response.getWriter().println("hello, scala!");
    val m:Slim3Model = new Slim3Model();
    m.setProp1(new Date().toString());
    Datastore.put(m);
    val meta:Slim3ModelMeta = Slim3ModelMeta.get()
    Datastore.query(meta).asList().foreach{ model =>
      response.getWriter().println(model.getProp1())
    }
    response.flushBuffer();
    return null;
  }
}

pom.xmlがあるディレクトリでMavenコマンドを実行してコンパイルします。

mvn install

コンパイルが成功したらAppEngine Java SDK付属の
開発用サーバーを起動してみましょう。
dev_appserver.sh war


起動後に表示されるローカルのURLにアクセスして
「hello, scala」
と表示されていればとりあえず成功です。

毎回Javaで生成されたファイルをScalaに移動なんてやってられねーよ!!
という方のためにScala用の生成タスクを開発してくださった方がいます!


今回はまだ試してはいないのですが(すみません・・・)、
素敵なことにコントローラ、サービスの生成はもちろん、テストのひな形も
Scalaのテストツールで生成されるみたいです。

とりあえず今回はこの辺りで。