ホーム ブログ ページ 46

超簡単!!なTestLinkの使い方

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回はテスト管理ツール「TestLink」の使い方をスライド形式で紹介します。

■ 概要

「TestLink」はテスト管理ツールと呼ばれるもののひとつで、テスト項目を作って、それをテストして…という手順を一元管理する為のパッケージとなっています。

しかしこの TestLink。テスト管理ツールといえば!というくらい普及しているにもかかわらず、最新バージョンの日本語ドキュメントがなかったり、本体の翻訳も中途半端だったりと、少しとっつきにくい印象があります。

そこではじめての方にもわかるように、「できるだけわかりやすく」を意識して、スライドを作成しました。 少しでも参考にしていただければ幸いです。

■ 本編(スライド)

■ 参考文献

[小ネタ] トップレベルの定数(クラス/モジュール)の取得

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ネストしたクラスなどの内部からトップレベルの定数を呼び出す小ネタ

 クラスが呼び出せない!

Rubyでは「ModuleA::ModuleB::ClassC」のようにモジュールやクラスの中に子クラスを作って名前空間をわけることができるようになっています。

module A
  module B
    class C
      def self.test
        return B
      end
    end
  end
end

class B
end

上記コードではモジュールBとクラスBで名前が被っていますが、スコープが異なるので問題ありません。

ここでA::B::C.testを実行すると

モジュールA::B

が返ってきます。

クラスA::B::C内部からトップレベルにあるクラスBを呼び出したい場合はどうすればよいでしょうか。

 解決策

return B

としていた箇所を

return ::B

のように演算子”::”をつけて呼び出すだけです。

設計をちゃんとしろよ、という声も聞こえてきそうですが

依存ライブラリなどの都合で名前を変えることができないということは、よくあります。

とはいえ同じ名前のモジュール・クラスなどの定数が散在しているのは

混乱の元となります。

開発する箇所ではまず、

汎用的すぎず(重複しにくく)可読性の高い命名を心がけたいものです。

————–

動作環境

CentOS 6.3

ruby 1.9.3p194

ホストベース認証

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rick No27です。
ssh接続等のパスワードを省略するもので、接続先に接続者と公開鍵とユーザを登録しておくことで可能となります。

設定方法

【接続元サーバ】
ホスト名:a-host
ユーザ名:aserver
【接続先サーバ】
ホスト名:b-host
ユーザ名:bserver

設定方法

a-hostの処理

$ su –
# ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -C ” -N ”
# scp /etc/ssh/ssh_host_rsa_key.pub b-hostのIP:/tmp/
sshdでないので注意
# vi /etc/ssh/ssh_config
—————————————
EnableSSHKeysign yes
HostbasedAuthentication yes
—————————————

b-hostの処理

$ su –
a-hostから送られてきた公開鍵をssh_known_hostsに書き込む
a-hostの後に半角の空白を開けていることに注意
# ( echo -n ‘a-host ‘ ; cat /tmp/ssh_host_rsa_key.pub ) >> /etc/ssh/ssh_known_hosts
# vi /etc/ssh/shosts.equiv
—————————————
a-host aserver
—————————————
# vi /etc/ssh/sshd_config
—————————————
HostbasedAuthentication yes
—————————————
# service sshd restart

接続

a-host

$ ssh bserver@b-host

Windows環境でnetbeansを使用して、Ruby&Rails開発を行う。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

自分がRuby&Rails開発の初心者です。

VisualStudioとEclipseでの開発が慣れた僕にっとて、vimエディターの開発はすごく不便です。いろいろ試して、netbeansを使用しています。

 前言

自分がRuby&Rails開発の初心者です。

VisualStudioとEclipseでの開発が慣れた僕にっとて、vimエディターの開発はすごく不便です。

vimのRailsプラグインを入れても、やりづらい感じです。

開発効率が良くないです。

いろいろ試して、下記の開発環境にしました。

実行環境:CentOS

開発環境:Windows

開発ツール:netbeans WinSCP

Windows環境で、netbeansでコーディングして、WinSCPを利用して、CentOSサーバにファイルを送ります。

僕と似たような方がいれば、参照できると思って、この記事を作成しました。

 vimエディタの不便

vimエディタでは、下記の行動はできないです。

・関数の宣言へ行く

・ファイルの比較

・関数を使用している箇所

・プロジェクト範囲の文字列検索/置換

・プロジェクト範囲のファイル検索

・インデント

・コミットする前に、修正箇所確認

etc

 NetBeans導入

NetBeans IDE 7.2はhttp://netbeans.org/から無料で入手できます。

Windows, Mac OS X, Linux, Solarisなどにインストール可能です。

JDKまたはJRE(バージョン6以上)が必要です。

http://www.oracle.com/technetwork/java/javase/downloads/index.htmlから入手(無料)してインストールしてください。

NetBeansではRuby on Railsの開発しかしない方は、ダウンロードバンドルから「すべて」を選んで、

インストール時にコンポーネントを「ベースIDE」だけに限定することをお勧めいたします。

 Ruby on Rails プラグインのインストール

  1. メニューから[ツール]→[プラグイン]を選択
  2. [設定]タブを選択
  3. [追加]ボタンをクリック
  4. [名前]に「Community Ruby」、[URL]に

 https://blogs.oracle.com/geertjan/resource/nb-72-community-ruby.xml と入力

  1. [OK]ボタンをクリック
  2. [使用可能なプラグイン]タブを選択
  3. [更新の確認]ボタンをクリック
  4. [検索]ボックスに「ruby」と入力
  5. [Ruby and Rails]にチェックを入れる
  6. [インストール]ボタンをクリック
  7. [次へ]ボタンをクリック
  8. [すべてのライセンス契約条件に同意する]をチェック
  9. [インストール]ボタンをクリック
  10. 「次のプラグインは署名されていますが信頼されていません」という警告が出たら[続行]ボタンをクリック
  11. [完了]ボタンをクリック

ここでNetBeansが再起動されます。

 NetBeansのメリット

いろいろな機能がありますが、ここで自分がよく使う機能を紹介します。

●自動補完機能

「.」を入力して、メソッドリストが表示されます。

●「使用情報を検索」

メソッド、クラス、変数、定数などを選択して、右クリックして、「使用情報を検索」を選択すれば、

使用している箇所が表示されます。

●ナビゲータ

ファイル内に定義したメソッド、定数、変数一覧が表示されます。

クリックすると、すぐ飛びます。

●フォーマット Alt+Shit+F

右クリック、フォーマット、インデント一括修正できます。

●名前変更(Ctrl+R)

一括変更できます。

●編集メニュー

検索

置換

プロジェクト内検索

プロジェクト内置換

●宣言へ移動

●GitとSubversion

差分とか確認しやすい。

GUIで修正箇所を比較してから、コミットできるため、ミスが生じしにくいです。

●同時に複数ファイルを開くことができます。

●GUIでファイル比較

 WinSCP

導入と利用方法は簡単なので、省略します。

ダウンロードURL:

http://sourceforge.jp/projects/sfnet_winscp/downloads/WinSCP/5.1.2/winscp512setup.exe/

VirtualBoxのゲストマシン(CentOS)の時刻ずれ問題の対策

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Ruby&Rails開発のために、VirtualBoxのゲストマシン(CentOS)を使用しています。

毎日、ゲストOSをシャットダウンせずに、「仮想マシンの状態を保存」を利用しています。

仮想マシンの状態を保存の機能が便利ですが、時刻ずれが生じしてしまいます。

Ruby&Rails開発のために、VirtualBoxのゲストマシン(CentOS)を使用しています。

毎日、ゲストOSをシャットダウンせずに、「仮想マシンの状態を保存」を利用しています。

仮想マシンの状態を保存の機能が便利ですが、時刻ずれが生じしてしまいます。

ログの不整合など問題があります。

毎日、dateコマンドで、時刻を直していますが、面倒です。

下記設定を実施すると、起動時に、自動的に時刻が正しく設定されます。

# vi /etc/ntp/step-tickers

下記のntpdサーバを追加する。

ntp.nict.jp

ntp.jst.mfeed.ad.jp

NTPサーバ停止

# /etc/rc.d/init.d/ntpd stop

NTPサーバ起動

# /etc/rc.d/init.d/ntpd start

一緒に始めようSencha Touch 2.0 入門編: 第2回 Sencha Touchで作れるUI

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

お久しぶりです。だーますです。

前回の投稿から5ヶ月程空いてしまいましたが、今回はSencha Touch 2.0で作ることができるUIについてざっくり解説させていただこうと思います。

 基本の書き方

前回と同じように、Sencha Touchのフォルダ(sencha-touch-2.0.1.1)が入った適当なフォルダを作ります。

※本稿執筆時点での最新版は2.1ですがそちらでもOKです

そこに、以下のようなファイルを置きます。

index.html

<!DOCTYPE html>
<html>
    <head>
        
        <title>Sencha Touch App</title>
        <link rel="stylesheet" type="text/css" href="sencha-touch-2.0.1.1/resources/css/sencha-touch.css" />
        <script type="text/javascript" src="sencha-touch-2.0.1.1/sencha-touch-all-debug.js"></script>
        <script type="text/javascript" src="app.js"></script>
    </head>
    <body></body>
</html>

app.js

Ext.application({
    viewport: {
        autoMaximize: true
    },
    launch: function() {
        Ext.Viewport.add({
            xtype: 'container',
            defaults: {
                margin: 5
            },
            items: [{
                // ここにUIを記述
            }]
        });
    }
});

要するに、sencha-touch.cssとsencha-touch-all-debug.jsが読み込まれ、その上でapp.jsの内容を実行できればOKです。

ここより先のソースコードは、Ext.Viewport.addの中身だけ記述させていただきます。

なお、”autoMaximize: true”はスマートフォンで閲覧した際にナビゲーションバーを隠す記述、

“defaults”内の”margin: 5″は子コンポーネントすべてにデフォルトで5pxのマージンを設定する記述です。

 Sencha Touch 2.0 のUI (一例)

コンテナー (container)

様々なUIを配置するための、基本となるコンポーネントです。

Ext.Viewport.add({
    xtype: 'container',
    html: 'Hello,World!'
});

入れ子構造もできます。”layout”で区切る方向を指定できます。

Ext.Viewport.add({
    xtype: 'container',
    defaults: {
        margin: 5,
    },
    items: [{
        xtype: 'container',
        layout: 'vbox',
        items: [{
            xtype: 'container',
            html: 'コンテナ1'
        }, {
            xtype: 'container',
            layout: 'hbox',
            items: [{
                xtype: 'container',
                html: 'コンテナ2'
            }, {
                xtype: 'container',
                html: 'コンテナ3'
            }]
        }]
    }]
});

ラベル (label)

ラベルです。文字を表示することに特化したコンポーネントです。

Ext.Viewport.add({
    xtype: 'container',
    defaults: {
        margin: 5
    },
    items: [{
        xtype: 'label',
        html: 'Hello,World!'
    }, {
        xtype: 'label',
        html: 'This is Sencha Touch 2.0'
    }]
});

ボタン (button)

ボタンです。”ui”を変えることで色や形状が変えられます。

Ext.Viewport.add({
    xtype: 'container',
    defaults: {
        margin: 5
    },
    items: [{
        xtype: 'button',
        text: 'button'
    }, {
        xtype: 'button',
        ui: 'action',
        text: 'ui:action'
    }, {
        xtype: 'button',
        ui: 'decline',
        text: 'ui:decline'
    }, {
        xtype: 'button',
        ui: 'confirm',
        text: 'ui:confirm'
    }, {
        xtype: 'button',
        ui: 'forward',
        text: 'ui:forward'
    }, {
        xtype: 'button',
        ui: 'back',
        text: 'ui:back'
    }, {
        xtype: 'button',
        ui: 'round',
        text: 'ui:round'
    }, {
        xtype: 'button',
        ui: 'small',
        text: 'ui:small'
    }]
});

テキストボックス (textfield)

テキストボックスです。”placeHolder”でプレースホルダを設定できます。

Ext.Viewport.add({
    xtype: 'container',
    defaults: {
        margin: 5
    },
    items: [{
        xtype: 'textfield'
    }, {
        xtype: 'textfield',
        placeHolder: 'this is textfield'
    }]
});

イメージ (img)

画像を表示するためのコンポーネントです。高さ・幅を、表示する画像に合わせて設定しておく必要があります。

Ext.Viewport.add({
    xtype: 'container',
    defaults: {
        margin: 5
    },
    items: [{
        xtype: 'img',
        src: 'icon.png',
        width: 57,
        height: 57
    }]
});

マップ (map)

Googleマップを表示できます。

Ext.Viewport.add({
    xtype: 'map',
    layout: 'fit'
});
http://doruby.kbmj.com/darmasu/files/002061.PNG

使うにはindex.htmlでGoogleマップのAPIを読み込んでおく必要があります。

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>

ツールバー (toolbar)

ツールバーです。”docked”によって画面の上や下に配置できます。

“ui”で色を変えられる他、ツールバー内にボタンやテキストボックスを設定することもできます。

Ext.Viewport.add({
    xtype: 'container',
    html: 'コンテナ',
    items: [{
        xtype: 'toolbar',
        docked: 'top',
        title: 'toolbar',
        items: [{
            xtype: 'button',
            ui: 'back',
            text: 'back'
        }]
    }, {
        xtype: 'toolbar',
        docked: 'bottom',
        ui: 'light',
        title: 'ui:light',
        items: [{
            xtype: 'button',
            text: 'button'
        }]
    }, {
        xtype: 'toolbar',
        docked: 'top',
        ui: 'neutral',
        items: [{
            xtype: 'textfield',
            placeHolder: 'textfield inside toolbar'
        }]
    }]
});

タイトルバー (titlebar)

toolbarの仲間ですが、役割が若干違います。

子コンポーネントの配置を”align”で変えられるのが大きな違いでしょうか。

Ext.Viewport.add({
    xtype: 'container',
    items: [{
        xtype: 'titlebar',
        title: 'TitleBar',
        items: [{
            xtype: 'button',
            align: 'left',
            text: 'left button'
        },{
            xtype: 'button',
            align: 'right',
            text: 'right button'
        }]
    }]
});

タブバー (tab)

タブによってページを切り替えるコンポーネントです。

画面上に配置する他、iOSでお馴染みの画面下タブもつくれます。

上に配置する場合
Ext.Viewport.add({
    xtype: 'tabpanel',
    items: [{
        xtype: 'container',
        title: 'tab 1',
        html: 'コンテナ1'
    }, {
        xtype: 'container',
        title: 'tab 2',
        html: 'コンテナ2'
    }]
});
下に配置する場合
Ext.Viewport.add({
    xtype: 'tabpanel',
    tabBarPosition: 'bottom',
    items: [{
        xtype: 'container',
        title: 'tab 1',
        iconCls: 'home',
        html: 'コンテナ1'
    }, {
        xtype: 'container',
        title: 'tab 2',
        iconCls: 'user',
        html: 'コンテナ2'
    }]
});

カルーセル (carousel)

フリックでページ切り替えを行うコンポーネントです。

Ext.Viewport.add({
    xtype: 'carousel',
    items: [{
        xtype: 'container',
        html: 'page 1',
        style: {
            // わかりやすいように各ページに色を付けてます
            'background-color': '#FFFFFF'
        }
    }, {
        xtype: 'container',
        html: 'page 2',
        style: {
            'background-color': '#AAAAAA'
        }
    }]
});

画面だけでは動きがわかりづらいので写真も用意しました。

フォーム (form)

色々な入力形式が使えるフォームです。以下は一例です。

Ext.Viewport.add({
    xtype: 'formpanel',
    items: [{
        xtype: 'fieldset',
        title: 'Form',
        items: [{
            xtype: 'textfield',
            label: 'text'
        }, {
            xtype: 'spinnerfield',
            label: 'spinner'
        }, {
            xtype: 'selectfield',
            label: 'select',
            options: [
                {text: 'option 1'},
                {text: 'option 2'},
                {text: 'option 3'}
            ]
        }, {
            xtype: 'datepickerfield',
            label: 'date'
        }, {
            xtype: 'sliderfield',
            label: 'slider'
        }, {
            xtype: 'togglefield',
            label: 'toggle'
        }]
    }]
});
selectfieldを呼び出した画面
datepickerfieldを呼び出した画面

リストビュー (list)

様々なデータを表示できるリストです。

Ext.Viewport.add({
    xtype: 'list',
    data: [
        {text: 'エインヘリアル'},
        {text: '黄金航路'},
        {text: '式姫草子'},
        {text: '星海'},
        {text: 'リトルデビルズダイアリー'}
    ]
});

この画像では、「式姫草子」をタップして選択状態にしました。

store, proxy, readerと組み合わせればAjaxやJSONPリクエストで取得したものを動的に表示できたりしますが、

それについてはいつかまた説明します。

 他にも魅力的なUIがいっぱい

Sencha Touch 2.0には他にも、前回取り上げたナビゲーションビューや、

ポップアップダイアログ、アクションシート、モーダルなどといった

魅力的なUIが揃っています。

そのすべてをここに記述するのは難しいので、

もっと知りたいという方は、是非ドキュメントKitchen Sink(サンプル集)をチェックしてみてください。(WebKitブラウザで見てください)

 次回予告

次回は、今回一緒に説明させていただく予定だったコンポーネントをクラス定義する方法も含め、

Sencha Touchのクラスシステムについて触れようと思います。

近日中に更新します。

Amazon EC2のインスタンスに固定のIPアドレス(Elastic IP)を持たせる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

間が開きましたが、引き続きAWSの記事です。

今回はAmazon EC2のインスタンスをに固定IPアドレス(Elastic IP。以下EIP)を設定する方法を紹介します。

1.AWS Management Console Homeにログイン

前回紹介したので省略します。

2.EC2 Management Consoleに移動

こちらも前回と同様

3.EIP一覧に移動

赤枠のリンクをクリック

4.EIPを新規発行

赤枠のボタンをクリック

確認画面が出るので、「EC2」を選択している事を確認して「Yes,Allocate」をクリック

成功するとEIP一覧にIPアドレスが追加されます。

この状態のままではEC2インスタンスと紐付けられていないので、さらに設定が必要です。

5.EIPをEC2インスタンスに関連付ける

発行したEIPにカーソルを合わせて右クリック⇒「Associate」をクリック

関連付ける対象のインスタンスを選択して「Yes,Associate」をクリック

成功すると、上記のようにEIP一覧にてインスタンスと関連付けられた事が分かるようになります。

また、インスタンス一覧から詳細を確認すると、画像の赤枠部分がこれまでのpublic DNSからEIPに変化している事がわかります。

あとは、EIPでインスタンスにSSHログイン出来る事等を確認すればOKです。

あとがき

今回は比較的簡単な設定のため、手順も少ないです。

public DNSのままではインスタンス再起動等の拍子に変化する場合があるとの事なので、実際に利用する際はEIPを発行しておいた方が便利だと思います。

エレコマの導入手順@FreeBSD

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


よしだです。

2週連続の投稿となる今回は、前回予告した通り FreeBSD へのエレコマの導入手順を紹介したいと思います。

0. Ports Collection + Ruby on Rails のインストール

今回はこの部分の説明を割愛します。

前回の記事『FreeBSD に任意バージョンの Ruby on Rails を導入する』が参考になると思います。

1. ImageMagick のインストール

まずは エレコマの商品画像処理に使われている ImageMagick を導入していきます。

今回はインストール前の設定で SVG ライブラリをインストールしないようにオプションから外しています。

これは SVG ライブラリインストールの際に GTK および X Window System が必要になって、不要な時間・ディスク容量を費やすのを避けるためです。

# cd /usr/ports/graphics/ImageMagick
# make config-recursive
(ここで ImageMagick の SVG オプションを解除)
# make install clean

2. PostgreSQL のインストール

今回 DB にはエレコマで公式サポートしている PostgreSQL を利用することにします。

サポートはされていませんが、MySQL での導入も可能です。

# cd /usr/ports/databases/postgresql83-server
# make install clean
# echo 'postgresql_enable="YES"' >> /etc/rc.conf
(次回ブート時に自動起動)
# /usr/local/etc/rc.d/postgresql initdb
(DB設定などがない状態なので、このコマンドで初期化)
# /usr/local/etc/rc.d/postgresql start
(サービス開始)

3. git のインストール

エレコマの最新ソースコードは GitHub から入手可能です。

ここではダウンロードに必要なバージョン管理ツール git をインストールしておきます。

# cd /usr/ports/devel/git
# make config-recursive
# make install clean

4. 必要な Gem のインストール

エレコマに必要となる Gem をインストールします。

一部古いバージョンの Gem も含まれますが、互換性を考え、README に合わせてインストールするのが無難でしょう。

# gem install rmagick -v 2.12.2
# gem install postgres
# gem install gettext -v 2.1.0
# gem install gruff -v 0.3.6
# fetch http://www.artonx.org/data/lhalib/lhalib-0.8.1.gem
# gem install lhalib-0.8.1.gem
# gem install webmock -v 1.3.4
# gem install thoughtbot-factory_girl -v 1.2.2 --source http://gems.github.com
# gem install json
# gem install daemons

5. 一般ユーザに切り替え

ここでエレコマを実際に動かすことになる一般ユーザに切り替えます。

今回は ec というユーザを作成し、このユーザの権限の元でエレコマを実行させます。

# pw useradd ec -m
# passwd ec
(パスワードは適当に elecoma を設定)
# su - ec

6. エレコマのダウンロード

一般ユーザに切り替えたところで、早速エレコマ本体をダウンロードします。

% git clone git://github.com/elecoma/elecoma.git
% cd elecoma

7. DB 設定をFreeBSD 向けに変更

次にデータベースの設定を FreeBSD に合わせて変更していきます。

エレコマの設定は CentOS に最適化されているので、PostgreSQL のデフォルトのユーザ名など、細かいところに相違があるようです。

% id postgres
id: postgres: no such user
(CentOS 版 PostgreSQL のデフォルトユーザ名 postgres が存在しない?!)
% id pgsql
uid=70(pgsql) gid=70(pgsql) groups=70(pgsql)
(FreeBSD では pgsql という名前で登録されています)

早速この点に修正を加えます。

% cp config/database.example.yml config/database.yml
% vim config/database.yml
(「portgres」となっている部分を「pgsql」に変更)
% diff config/database.yml config/database.example.yml
3c3
<   username: pgsql
---
>   username: postgres

8. 各種プラグインのインストール

エレコマに必要となるプラグインをインストールします。

これも Gem と同様に、一部古いプラグインが含まれますが、ここでは動作の安全性を優先します。

この部分は、ほぼ README のコピペになるので、リンク切れ等があるばあいは適宜修正して利用してください。

% ruby script/plugin install git://github.com/realityforge/rails-active-form.git
% ruby script/plugin install git://github.com/rails/acts_as_list.git
% ruby script/plugin install git://github.com/technoweenie/acts_as_paranoid.git
% ruby script/plugin install git://github.com/rails/acts_as_tree.git
% ruby script/plugin install http://topfunky.net/svn/plugins/ar_fixtures/
% ruby script/plugin install git://github.com/jpmobile/jpmobile.git -r 'tag 0.0.8'
% ruby script/plugin install http://taslam-plugins.googlecode.com/svn/trunk/jpmobile_emoticon_filter/
% cd vendor/plugins
% git clone git://github.com/tmtysk/mbmail.git mbmail
% cd mbmail
% git checkout 654ce3ec2dfa10ac3b05cd9354eb84456d206a6d
% rm -fr lib/jpmobile
% rm -fr .git
% cd ../../..
% ruby script/plugin install git://github.com/jamesgolick/resource_controller.git
% ruby script/plugin install git://github.com/mislav/will_paginate.git -r 'tag 2.3.6'
% cd vendor/plugins/
% git clone  git://github.com/mislav/will_paginate.git
% cd will_paginate/
% git checkout origin/2-3-stable
% cd ../../..
% ruby script/plugin install git://github.com/kakutani/yaml_waml.git
% ruby script/plugin install git://github.com/rails/ssl_requirement.git
% ruby script/plugin install git://github.com/DianthuDia/double_submit_protection.git
% ruby script/plugin install git://github.com/champierre/image_submit_tag_ext.git
% ruby script/plugin install git://github.com/dchelimsky/rspec-rails.git -r 'tag 1.2.9'
% ruby script/plugin install git://github.com/dchelimsky/rspec.git -r 'tag 1.2.9'

9. DBを作成する……しかし……

ここまできたら、次は DB の作成! となるのですが、どうやらうまく実行できないケースがあるようです。

今回インストールを試した環境では、下記のようなエラーが発生し、DB の作成が失敗してしまいました。

% rake db:create
WARNING: 'require 'rake/rdoctask'' is deprecated.  Please use 'require 'rdoc/task' (in RDoc 2.4.2+)' instead.
    at /usr/local/lib/ruby/gems/1.8/gems/rake-0.9.2.2/lib/rake/rdoctask.rb
rake aborted!
no such file to load -- iconv

エラーによれば iconv というライブラリが不足しているようなので、これをインストールします。

ここで注意点は、iconv そのものではなく、Ruby 向けの ruby-iconv をインストールしなければならないことです。

% exit
# cd /usr/ports/converters/ruby-iconv
# make install
# su - ec

無事にインストールが終われば、ec ユーザに戻り、もう一度 DB 作成に挑戦します。

10. あらためて DB 作成を作成する

必要なライブラリを揃えたところで、もう一度 DB の作成を実行します。

今度はうまくいき、DBの作成に成功します(※1)。

% rake db:create

11. DB を初期化する

データベースにテーブルを作成します。

また、管理画面へのアクセスに必要な管理者情報も、この段階でデータベースに登録しておきます。

% rake db:migrate
% rake db:fixtures:load FIXTURES=admin_users

12. エレコマを起動する!

最後に Rails の簡易サーバを利用して、エレコマを立ち上げます。

% ruby script/server

http://<エレコマをインストールしたマシンのIPアドレス>:3000/ にアクセスすると、エレコマのトップページが確認できます!

 最後に

今回は史上初となる(?)エレコマの FreeBSD への導入とその手順を紹介しました。

エレコマに関する設定や細かいインストール手順をかなり端折って説明しているので、詳しい説明については下記の関連記事を参照していただければ幸いです。

  1. ECサイト構築パッケージ「エレコマ」のインストール手順@Ubuntu 10.10
  2. ECサイト構築パッケージ「エレコマ」の初期設定@Ubuntu 10.10

 備考

※1 DB 作成時に発生する WARNING への対処

手順 10. の段階で DB の作成には成功しますが、下記のような WARNING が出力されてしまいます。

% rake db:create
WARNING: 'require 'rake/rdoctask'' is deprecated.  Please use 'require 'rdoc/task' (in RDoc 2.4.2+)' instead.
    at /usr/local/lib/ruby/gems/1.8/gems/rake-0.9.2.2/lib/rake/rdoctask.rb
WARNING: Global access to Rake DSL methods is deprecated.  Please include
    ...  Rake::DSL into classes and modules which use the Rake DSL methods.
WARNING: DSL method Spec::Rake::SpecTask#task called at /home/ec/elecoma/lib/tasks/rspec.rake:15:in `initialize'
(以下略)

どうやらこれは rake 0.9 と Rails 2 の相性が悪いことに起因するもののようです。

そういうわけで rake をダウングレードしてみます。

% rake --version
rake, version 0.9.2.2
(このバージョンと Rails の相性が悪いらしい)
% exit
# gem uninstall rake
(本当に消しても良いか、と聞かれるので Y[Enter] で続行)
# gem install rake -v=0.8.7
# su - ec
% rake db:create

ダウングレード後にDB 作成を実行すると、今度は WARNING が出力されず、無事に DB が作成できます。

FreeBSD に任意バージョンの Ruby on Rails を導入する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

よしだです。

今回は FreeBSD に任意バージョンの Ruby + Ruby on Rails を導入する方法を紹介します。

 概要

FreeBSD ではソフトウェアのインストールに Ports Collection というシステムを利用します。

このシステムを利用して Ruby + Ruby on Rails をインストールすると、デフォルトでは Ruby 1.8 と Rails 3.2 が入ります(FreeBSD 8.3 の場合)。ところが、Ruby や Ruby on Rails はバージョンによってかなり挙動が違ってきます。特定のバージョンをインストールしたいというシーンは少なからずあると思います。

そこで今回は、FreeBSD の Ports Collection を利用して、簡単に任意バージョンの Ruby + Ruby on Rails を導入する方法を紹介します。

 導入手順

0. Ports Collection をインストールする

FreeBSD インストール直後で Ports Collection の導入が済んでいない場合は、root ユーザで下記のコマンドでインストールします。

# portsnap fetch
# portsnap extract

これで /usr/ports 以下に、各ソフトウェアのインストールに必要なファイルがまとめられたディレクトリ(このまとまりをスケルトンといいます)がカテゴリ分けされた状態で配備されます。

1. 任意バージョンの Ruby をインストールするための準備

Ports Collection からは Ruby 1.8 か Ruby 1.9 を導入することができます。

Ruby に依存するソフトウェを導入する際に、デフォルトでは Ruby 1.8 がインストールされます。

ここで Ruby 1.9 をインストールしたい場合は、/etc/make.conf に Ruby 1.9 を利用することを明示することで実現できます。

# echo 'RUBY_DEFAULT_VER=1.9' >> /etc/make.conf

どちらのバージョンを導入するにしても、Ruby 自体のインストールを明示的に行う必要はなく、Ruby が必要になったときに Ports Collection が自動で導入してくれます。便利ですね。

2. RubyGems をインストールする

まずは Ruby on Rails に必要不可欠であるプラグインシステム、RubyGems をインストールします。

RubyGems はさまざまなプラグインの管理を行う一方で、Ruby on Rails のインストールまで行えるという優れものです。FreeBSD には、この RubyGems を最小限構成で導入するための port スケルトンが用意されています。

今回はこれを利用することで導入にかかる時間の短縮を図ります。

# cd /usr/ports/www/rubygem-rails-app-installer
# make config-recursive
(インストール時の設定を、依存ソフトウェア分もあわせて先に済ませてしまう)
# make install clean
(ここで Ruby とその他の必要なソフトウェアがインストールされる)

ここでのポイントは、インストール前に「make config-recursive」というコマンドを実行することです。

このコマンドはソフトウェアに必要な設定を、依存するソフトウェアの分も含めて、あらかじめ行うことができます。こうすることで、ソフトウェアごとに設定ダイアログが出現し、インストール作業が中断されるのを防ぐことができます。

3. 任意バージョンの RubyGems をインストールする

(この手順は、必要がなければ飛ばしてもかまいません)

RubyGems にもバージョンがあり、環境によっては特定バージョンの導入が必要なケースもあります。

FreeBSD 上には、バージョンごとの RubyGems の port スケルトンは存在しません。

そこで下記のように、RubyGems 自身の機能を利用してアップグレードもしくはダウングレードさせます。

# rehash
(先ほど gem コマンドが入ったばかりなので、csh の場合、PATH の再読み込みが必要)
# gem install rubygems-update -v=<インストールしたいバージョンの番号>
# rehash
(先ほどのコマンドで update_rubygems コマンドが入ったばかりなので、同上)
# update_rubygems

4. 任意バージョンの Ruby on Rails をインストールする

ここまでの手順で Ruby on Rails を導入するための準備は整いました。

Ruby on Rails は RubyGems を利用することで、簡単に導入することができます。

# gem install -v=<インストールしたいバージョンの番号> rails

とっても簡単ですね。

 おわりに

今回は FreeBSD 8.3 での利用を例に、任意バージョンの Ruby + Ruby on Rails を導入する方法を紹介しました。

次回はこの手順を利用して、Ruby on Rails 2.3 という少し古いシステムが必要になる『エレコマ』を、FreeBSD に導入する方法を紹介したいと思います。

アプリからサクサクお買いもの『DHCオンラインショップ』のレビュー

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


大変ご無沙汰しております。アプリレビューアです。

私がレビューしないうちにAndroid端末もかなり普及し、またアプリのトレンドもどんどん変わってきているかと思っていますが、そんな中、弊社では最近、ECアプリをお手伝いさせていただく機会が増えています。
 
そして、数あるECアプリの中で、弊社が自信を持ってお勧めさせていただくのが、今回のDHCオンラインショップアプリ(iPhone版/Android版)です!
お勧めのポイントは何と言っても、使いやすいこと!
DHC様の素敵な商品がアプリからサクサクお買いもの出来ちゃいます。
 
このシンプルで見やすい画面が使いやすいポイントです。
 
また、商品の検索はもちろんのこと、セール情報や売れ筋ランキングもここからチェックできます。
 
 
検索結果一覧はこんな感じ。

ここから売れ筋順/新着順/価格が安い順等の並べ替え検索もできます。
 
 
どこにいてもスマホから手軽に、サクサクお買いものが出来るのは便利ですね。
 
また、お気に入りの商品がキャンペーン価格になったら自動でお知らせ(Push通知)してくれる、アプリならではの便利機能も搭載!
これで、いつも購入しているサプリのセールも見逃しません。
 
アプリの価格は無料です。iPhone版もAndroid版もあります。
iPhone版ダウンロードはこちらから
Android版ダウンロードはこちらから
 
お買い物がどんどん便利になってきて、また今後どんな機能が追加されるのか、楽しみですね。

redmine ガントチャート チケットの開始日順でソートする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

redmine ガントチャート チケットの開始日順でソートする

 Redmineでタスク管理

Redmineで公私含めたタスクの管理を行っています。

なんといってもガントチャートが出るのが便利ですね。

Redmineでタスク管理を行うノウハウについては

ほかにたくさんの優れた情報がありますのでここでは詳しくは触れませんが、

個人的にガントチャートを出したいという点を踏まえて気をつけていることは

・チケットには必ず開始日、期日を入力する

・進捗(~%)をつけていく

という点です。

きっちりしすぎると管理コストが高くなりますので、あまり原則にとらわれずにやってます。

本記事はRedmine trunkバージョン リビジョン10485 をもとに書いています。

記事内でソースコードを変更する箇所がありますが、利用する場合は自己責任でお願いします。

 ガントチャートがちょっとみづらい?

本題に入っていきます。

ガントチャートを見てみましょう。

チケット#6の中に子チケットが並んでいます。

現時点ではソートがチケット番号順になっていて、どの順番で作業を行うか少しみづらいです。

 ソース改修

ソート順を変えるため、ソースを変更します。

下記は改修後のソースをsvn diffした結果です。

Index: lib/redmine/helpers/gantt.rb
===================================================================
--- lib/redmine/helpers/gantt.rb        (リビジョン 10485)
+++ lib/redmine/helpers/gantt.rb        (作業コピー)
@@ -638,7 +638,21 @@

       # Sorts a collection of issues by start_date, due_date, id for gantt rendering
       def sort_issues!(issues)
-        issues.sort! { |a, b| gantt_issue_compare(a, b, issues) }
+        default_date = Date.new(1970, 1, 1)
+        issues.sort! do |a, b|
+          a_is_child = a.id != a.root_id ? 1 : 0
+          b_is_child = b.id != b.root_id ? 1 : 0
+          a_start_date = a.start_date || default_date
+          b_start_date = b.start_date || default_date
+          a_child_start_date = Issue.find(a.root_id).children.minimum(:start_date)
+          b_child_start_date = Issue.find(b.root_id).children.minimum(:start_date)
+          a_root_start_date = a_child_start_date || a_start_date
+          b_root_start_date = b_child_start_date || b_start_date
+          (a_root_start_date <=> b_root_start_date).nonzero? ||
+            (a.root_id <=> b.root_id).nonzero? ||
+            (a_is_child <=> b_is_child).nonzero? ||
+            (a_start_date <=> b_start_date)
+        end
       end

       # TODO: top level issues should be sorted by start date

第一ソート: チケットの開始日(子チケットを持つ場合は子チケットの中で最も古い開始日)

第二ソート: 親チケットのチケット番号

第三ソート: チケットの開始日

と複数の条件でソートしています。

ここで単純にチケットの開始日順だけでソートしてしまうと、親チケットは開始日情報を持たずにエラーとなります。また強制的に何か日付を持たせると今度はチケットの親子関係が崩れてしまい、これまたみづらい状況になってしまいます。

 改修後のガントチャート

開始日順になっています。

チケットの親子関係も崩れていないですね。

見やすくなりました。

VirtualBoxの仮想ディスクを圧縮したい

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

VirtualBoxを開発環境に使い、データベースのインポート等繰り返すと仮想ディスクがどんどん肥大化します。

仮想ディスクを圧縮する方法を紹介します。

 VirtualBoxの仮想ディスクの肥大化

VirtualBoxで開発に利用しておりますが、使うにつれ仮想ディスクのサイズがどんどん大きくなります。

仮想ディスクを最適化したい!

今回は、以下の条件での説明になります

ホストOSWindows
ゲストOSLinux

 ゲストOSの不要ファイルの削除

不要なデータベースを削除します。(小職の環境には不要なデータベースをたくさん作ってしまった、今は不要になったため削除する)

不要なファイルを削除する。

 開発時に作成した不要なファイルを削除します。

 空き容量のゼロ埋め

以下のコマンドをゲストOS上で実行する。

dd if=/dev/zero of=zero bs=4k; \rm zero

 VirtualBoxに含まれるツールで最適化

以下を実行すると、最適化が始まります。。。しばらく待ちます。

VBoxManage modifyvdi “D:\SYSTEM_DEVELOPMENT\SYSTEM_DEVELOPMENT.vdi” compact

0%…10%…20%…30%…40%…50%…60%…70%…

100% になり処理が終わると。。。

           ↓のように小さくなりました!

みなさんも、仮想ディスクの肥大化に困った際は、お試しください。

ios6 UICollectionView を試してみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ios6から追加されたUICollectionViewのサンプルを作成してみました。

実装画面

下記が実装したアプリ画面です。

UICollectionViewDemoController.h

#import <uikit /uikit.h>

@interface UICollectionViewDemoController : UIViewController 
<uicollectionviewdatasource , uicollectionviewdelegate> {
    UICollectionView *_collectionView;
}

@property (nonatomic, retain) UICollectionView *collectionView;


@end

UICollectionViewDemoController.m

#import "UICollectionViewDemoController.h"

@interface UICollectionViewDemoController (Private)
- (void)setUp;
- (CGFloat)getRandInt:(int)min max:(int)max;
@end


@implementation UICollectionViewDemoController


- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setUp];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)setUp
{
    UICollectionViewFlowLayout *flowLayout = [[[UICollectionViewFlowLayout alloc] init] autorelease];
    [flowLayout setItemSize:CGSizeMake(79, 80)];
    [flowLayout setMinimumLineSpacing:1.0f];
    [flowLayout setMinimumInteritemSpacing:1.0f];
    //[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    
    UICollectionView *collectionView = 
[[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout] autorelease];
    self.collectionView = collectionView;
    self.collectionView.delegate   = self;
    self.collectionView.dataSource = self;
    
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
    [self.view addSubview:self.collectionView];
}

-(CGFloat)getRandInt:(int)min max:(int)max {
	static int randInitFlag;
	if (randInitFlag == 0) {
		srand(time(NULL));
		randInitFlag = 1;
	}
	return min + (rand()*(max-min+1.0)/(1.0+RAND_MAX));
}

#pragma UICollectionViewDelegate

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 1000;
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

#pragma UICollectionViewDataSource

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell =
 [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];

    CGFloat red   = [self getRandInt:1 max:1000] / 1000;
    CGFloat green = [self getRandInt:1 max:1000] / 1000;
    CGFloat blue  = [self getRandInt:1 max:1000] / 1000;
    
    UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
    [cell setBackgroundColor:color];
    
    return cell;
}


@end

以上です。

Postgresqlでカレンダーを使わずに日付を列挙する方法(generate_series)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回、カレンダーテーブルを使わずに日付を列挙する方法を書きます。

 運用中のシステムでカレンダーと結合したい要求が発生!

カレンダーテーブルを作りたいが、データベースにテーブル追加ができない場合、どうしよう?

 generate_series

Postgresql8.xから、generate_series という集合関数が出来た。

version 8と9で拡張されているので注意

 9.xの場合

関数引数型戻り型説明
generate_series(start, stop)intまたはbigintsetof intまたはsetof bigint(引数の型と同一)startからstopまで、刻み1で連続する値を生成します。
generate_series(start, stop, step)intまたはbigintsetof intまたはsetof bigint(引数の型と同一)startからstopまで、刻みstepで連続する値を生成します。
generate_series(start, stop, step interval)timestamp または timestamp with time zonesetof timestamp または setof timestamp with time zone(引数型と同じ)startからstopまで、刻みstepで連続する値を生成します。

SELECT * FROM generate_series(‘2008-03-01 00:00’::timestamp,

‘2008-03-04 12:00′, ’10 hours’);

generate_series

———————

2008-03-01 00:00:00

2008-03-01 10:00:00

2008-03-01 20:00:00

2008-03-02 06:00:00

2008-03-02 16:00:00

2008-03-03 02:00:00

2008-03-03 12:00:00

2008-03-03 22:00:00

2008-03-04 08:00:00

(9 rows)http://www.postgresql.jp/document/9.1/html/functions-srf.html

これを使って日付の列挙をしてみる。

6月一か月分の日付を以下のSQLで取得してみる。

SELECT

*

FROM

generate_series( cast(‘2012/06/01’ as timestamp) ,

DATE_TRUNC(‘month’, cast(‘2012/06/01’ as timestamp) + ‘1 months’) + ‘-1 days’,

‘1 days’)

以下のように出力出来ました。

generate_series

———————

2012-06-01 00:00:00

2012-06-02 00:00:00

2012-06-03 00:00:00

2012-06-04 00:00:00

2012-06-05 00:00:00

2012-06-06 00:00:00

2012-06-07 00:00:00

2012-06-08 00:00:00

2012-06-09 00:00:00

2012-06-10 00:00:00

2012-06-11 00:00:00

2012-06-12 00:00:00

2012-06-13 00:00:00

2012-06-14 00:00:00

2012-06-15 00:00:00

2012-06-16 00:00:00

2012-06-17 00:00:00

2012-06-18 00:00:00

2012-06-19 00:00:00

2012-06-20 00:00:00

2012-06-21 00:00:00

2012-06-22 00:00:00

2012-06-23 00:00:00

2012-06-24 00:00:00

2012-06-25 00:00:00

2012-06-26 00:00:00

2012-06-27 00:00:00

2012-06-28 00:00:00

2012-06-29 00:00:00

2012-06-30 00:00:00

(30 rows)

 8.xの場合

関数引数型戻り値の型説明
generate_series(start, stop)int または bigintsetof int またはsetof bigint (引数の型と同一)startからstopまでの刻み1で連続する値を生成します。
generate_series(start, stop, step)int または bigintsetof int または setof bigint (引数の型と同一)startからstopまでの刻みstepで連続する値を生成します。

select current_date + s.a as dates from generate_series(0,14,7) as s(a);

dates

————

2004-02-05

2004-02-12

2004-02-19

(3 rows)http://www.postgresql.jp/document/pg800doc/html/functions-srf.html

以下のSQLで先ほどと同様に6月の一か月分の日付を出力してみます。

SELECT

to_char( ‘2012-06-01’::Date + arr.i, ‘YYYY/MM/DD’ ) as date1

FROM

generate_series( 0,

(select EXTRACT(DAY FROM DATE_TRUNC(‘month’, cast(‘2012/06/01’ as timestamp) + ‘1 months’) + ‘-1 days’) – 1)::int

) as arr(i)

date1

————

2012/06/01

2012/06/02

2012/06/03

2012/06/04

2012/06/05

2012/06/06

2012/06/07

2012/06/08

2012/06/09

2012/06/10

2012/06/11

2012/06/12

2012/06/13

2012/06/14

2012/06/15

2012/06/16

2012/06/17

2012/06/18

2012/06/19

2012/06/20

2012/06/21

2012/06/22

2012/06/23

2012/06/24

2012/06/25

2012/06/26

2012/06/27

2012/06/28

2012/06/29

2012/06/30

(30 rows)

 応用

この日付一覧をテーブルと結合してみます。

以下のデータを例とします。

テーブル名:test1

idfield1create_date
1test2012-09-01
2test22012-09-01
3test32012-09-09

9.xの場合

SELECT

cal.date1,

COALESCE( test1_date.cnt, 0 ) as cnt

FROM

  • 日付一覧

(SELECT

to_char(arr,’YYYY/MM/DD’) as date1

FROM

generate_series( cast(‘2012/09/01’ as timestamp) ,

DATE_TRUNC(‘month’, cast(‘2012/09/01’ as timestamp) + ‘1 months’) + ‘-1 days’,

‘1 days’) as arr

) as cal

  • 結合テーブル

LEFT JOIN

(

SELECT

to_char(create_date, ‘YYYY/MM/DD’) as date2,

count(*) as cnt

FROM

test1

GROUP BY

date2

) as test1_date

ON cal.date1 = test1_date.date2

ORDER BY

cal.date1

以下のように集計結果が出ました。

date1 | cnt

————+—–

2012/09/01 | 2

2012/09/02 | 0

2012/09/03 | 0

2012/09/04 | 0

2012/09/05 | 0

2012/09/06 | 0

2012/09/07 | 0

2012/09/08 | 0

2012/09/09 | 1

2012/09/10 | 0

2012/09/11 | 0

2012/09/12 | 0

2012/09/13 | 0

2012/09/14 | 0

2012/09/15 | 0

2012/09/16 | 0

2012/09/17 | 0

2012/09/18 | 0

2012/09/19 | 0

2012/09/20 | 0

2012/09/21 | 0

2012/09/22 | 0

2012/09/23 | 0

2012/09/24 | 0

2012/09/25 | 0

2012/09/26 | 0

2012/09/27 | 0

2012/09/28 | 0

2012/09/29 | 0

2012/09/30 | 0

8.xの場合

SELECT

cal.date1,

COALESCE( test1_date.cnt, 0 ) as cnt

FROM

  • 日付一覧

(

SELECT

to_char( ‘2012-09-01’::Date + arr.i, ‘YYYY/MM/DD’ ) as date1

FROM

generate_series( 0,

(select EXTRACT(DAY FROM DATE_TRUNC(‘month’, cast(‘2012/09/01’ as timestamp) + ‘1 months’) + ‘-1 days’) – 1)::int

) as arr(i)

) as cal

  • 結合テーブル

LEFT JOIN

(

SELECT

to_char(create_date, ‘YYYY/MM/DD’) as date2,

count(*) as cnt

FROM

test1

GROUP BY

date2

) as test1_date

ON cal.date1 = test1_date.date2

ORDER BY

cal.date1

以下のように集計結果が出ました。

date1 | cnt

————+—–

2012/09/01 | 2

2012/09/02 | 0

2012/09/03 | 0

2012/09/04 | 0

2012/09/05 | 0

2012/09/06 | 0

2012/09/07 | 0

2012/09/08 | 0

2012/09/09 | 1

2012/09/10 | 0

2012/09/11 | 0

2012/09/12 | 0

2012/09/13 | 0

2012/09/14 | 0

2012/09/15 | 0

2012/09/16 | 0

2012/09/17 | 0

2012/09/18 | 0

2012/09/19 | 0

2012/09/20 | 0

2012/09/21 | 0

2012/09/22 | 0

2012/09/23 | 0

2012/09/24 | 0

2012/09/25 | 0

2012/09/26 | 0

2012/09/27 | 0

2012/09/28 | 0

2012/09/29 | 0

2012/09/30 | 0

このように、generate_series関数を駆使すれば、カレンダーテーブルが無くとも

データの集計処理に使えます。

generate_series関数は他にも使い方があるので、詳しくは、PostgreSQLのドキュメントを参照ください。

サーバ単体に負荷テストを行う「stress」

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Web開発では負荷テストというとjmeter や ab を思い浮かべますが、今回はマシン単体に直接負荷をかけるツール「stress」を使用します。

 このツールの便利なところ3点

  1. インストール手順が簡単。
  2. ネットワークには余計な負荷をかけない。
  3. 使い方が簡単でリソースの使用量を直接指定できる。

 入手からインストールまでの流れは次のとおりです。

入手方法:下記ページにてダウンロードしました。

http://weather.ou.edu/~apw/projects/stress/

 今回調査したかったマシンのOSは CentOS6 でしたのでリンク先の下記 rpmファイルをインストールすることにしました。

http://apt.sw.be/redhat/el6/en/i386/rpmforge/RPMS/stress-1.0.2-1.el6.rf.i686.rpm

インストール:

# rpm -ivh stress-1.0.2-1.el6.rf.i686.rpm 
警告: stress-1.0.2-1.el6.rf.i686.rpm: ヘッダ V3 DSA/SHA1 Signature, key ID 6b8d79e6: NOKEY
準備中...                ########################################### [100%]
   1:stress                 ########################################### [100%]

 ちなみに Debian系といった apt が使用できるOSでは apt-get install stress でインストールできるそうです。

使い方について:

 引数を渡さずに実行すると使用方法が表示されます。

# stress 
`stress' imposes certain types of compute stress on your system

Usage: stress [OPTION [ARG]] ...
 -?, --help         show this help statement
     --version      show version statement
 -v, --verbose      be verbose ← 詳細なメッセージを出力
 -q, --quiet        be quiet
 -n, --dry-run      show what would have been done
 -t, --timeout N    timeout after N seconds ← 負荷をかける時間を指定
     --backoff N    wait factor of N microseconds before work starts
 -c, --cpu N        spawn N workers spinning on sqrt() ← CPU負荷をかけるワーカーの数を指定
 -i, --io N         spawn N workers spinning on sync() ← IO負荷のワーカー数


 -m, --vm N         spawn N workers spinning on malloc()/free() ← メモリ負荷のワーカー数


     --vm-bytes B   malloc B bytes per vm worker (default is 256MB)← 使用するメモリ量を指定


     --vm-stride B  touch a byte every B bytes (default is 4096)
     --vm-hang N    sleep N secs before free (default is none, 0 is inf)
     --vm-keep      redirty memory instead of freeing and reallocating
 -d, --hdd N        spawn N workers spinning on write()/unlink()
     --hdd-bytes B  write B bytes per hdd worker (default is 1GB)
     --hdd-noclean  do not unlink files created by hdd workers

Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s

Note: Numbers may be suffixed with s,m,h,d,y (time) or B,K,M,G (size)

好みの引数を渡して実行してください。別のプロンプトで接続し top や vmstat などを表示していると負荷状態の変化が見れて面白いです。

例:メモリ負荷をどんどん上げていく。

stress –cpu 2 –io 2 –vm 2 –vm-bytes 512M –timeout 60s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 1024M –timeout 600s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 2048M –timeout 1200s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 4096M –timeout 1200s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 3072M –timeout 1200s

 負荷の上げ過ぎで stress が起動しなくなったのでさげた。

タイムアウト設定した時間より前に停止させるには Ctrl + C を押します。

必要なライブラリ:

# ldd /usr/bin/stress 
        linux-gate.so.1 =>  (0x00d0c000)
        libm.so.6 => /lib/libm.so.6 (0x0048c000)
        libc.so.6 => /lib/libc.so.6 (0x00e3a000)
        /lib/ld-linux.so.2 (0x008d9000)

 インストールがうまくいかない場合などご参照ください。

postgresqlでデータベース間でテーブル結合する方法(dblink)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

postgresqlでデータベース間でテーブル結合する方法を紹介します。

 dblink

contlibにdblinkというモジュールが登録されているのでこれを利用する。

windowsのインストーラーからインストールした場合同梱されています。

以下のデータベースを例に記載します

データベース host名
db1カレントのデータベースhost1
db2接続先のデータベースhost2

テーブル

データベース名テーブル名
db1table1
db2table2

table1のフィールド

フィールド名
db1_field1int
db1_field2text
db1_field3timestamp

table2のフィールド

フィールド名
db2_field1int
db2_field2text
db2_field3timestamp

 データベースにモジュールを適用する。

ログインする

psql -U [ユーザ―名] -d [モジュールを適用するデータベース名]

モジュールをインストール

create extension dblink;

これでインストールされます。

 接続

以下のSQLを発行すると’接続名’で定義した名前でコネクションを生成します。

select dblink_connetct(‘接続名’,’host=host2 port=5432 dbname=db2 user=xxx password=xxx’);

 切断

以下のSQLを発行すると’接続名’で定義したコネクションを切断します。

select dblink_disconnect(‘接続名’);

 接続先のデータベースにSELECT文を実行するには

上記の接続を実行後に以下のSQL実行することで、値が取得出来ます。

※SQLの返り値の型指定をしないとけないのが面倒。

select *

from dblink(‘接続名’,’ select db2_field1, db2_field2, db2_field3 from table2 ‘)

as t1 ( db2_field1 int, db2_field2 text, db2_field3 timestamp)

 このままでは、SQLが複雑になるのでビューにするとよい。

以下のようにビューを作ると。。。

create view db2_view as

select *

from dblink(‘接続名’,’ select db2_field1, db2_field2, db2_field3 from table2 ‘)

as t1 ( db2_field1 int, db2_field2 text, db2_field3 timestamp);

通常のテーブルのようにSQLが発行出来る。

select * from db2_view;

カレントデータベースにあるテーブルと結合してみる。

普通の結合文のように実行すれば結果が取得出来ます。

select db1.*, db2_view.* from db1

join db2_view on db2_view.db2_field1 = db1.db1_field1;

このように、データベースが異なる場合でもテーブル結合ができるので

活用してみてはいかがでしょうか?

詳細は、PostgreSQLのドキュメント、付録 F.追加で提供されるモジュールの項のdblinkに詳しく書いてあります。

http://www.postgresql.jp/document/9.1/html/dblink.html

DBの実データサイズを調べる(PostgreSQL編)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

DBを運用していると、どのテーブルが実際にどれくらいのファイルサイズなのかを知りたい場面があるかと思います。

そんな時、DBが使用している実データサイズを調べる方法を説明したいと思います。(データベース/テーブル)

今回はPostgreSQLが対象です。※9.1で確認しました。おそらく8系でも同じ方法かと思います

 データベースの実データサイズを調べる

データベースにはそれぞれoidという識別子が設定されています。

そして、実際にデータが格納されているディレクトリ名にもこのoidが付いています。

ですので、このoidが分かれば、あとは該当のディレクトリのサイズを調べることで、データベースの実データサイズが分かるのです。

oidはpg_stag_databaseという稼働統計情報から調べることができます。

# select datid,datname from pg_stat_database;
 datid  |            datname             
--------+--------------------------------
      1 | template1
  12172 | template0
  12180 | postgres
  30310 | hoge

このdatidというのがデータベースのoidです。hogeデータベースのoidは30310ということになります。

次にPostgreSQLのデータディレクトリから30310という名前のディレクトリを探します。

※データディレクトリの場所は環境やinitdb時の指定により異なります。よく使われるのは/usr/local/pgsql/data/などでしょうか。

[/usr/local/pgsql9.1/data/base]$ du -sh ./*
5.7M    ./1
5.7M    ./12172
5.8M    ./12180
 32M    ./30310
  0B    ./pgsql_tmp

duなどでディレクトリのファイルサイズを調べます。30310は32Mなので、hogeの実データサイズは32MBだと判明しました!

 テーブルの実データサイズを調べる

テーブルの実データサイズの調べ方も基本はデータベースと同じです。

テーブルのoidを調べ、データディレクトリから同じidのディレクトリを探します。

oidはpg_classのrelfilenodeカラムで確認できます。

hoge=# select relfilenode,relname from pg_class order by relname;
 relfilenode |                             relname                             
-------------+-----------------------------------------------------------------
       11868 | _pg_foreign_data_wrappers
       11877 | _pg_foreign_servers
       11886 | _pg_foreign_tables
       11896 | _pg_user_mappings
       30311 | users

usersテーブルのoidは30311だと分かりました。あとは先程調べたhogeデータベースのデータディレクトリ内の同名ディレクトリのファイルサイズを調べればOKです。

[/usr/local/pgsql9.1/data/base/30310]$ du -sh ./* | grep 30311
 16K    ./30311
 24K    ./30311_fsm

grepすると2件ヒットしますが、30311_fsmの方はVACUUM で発見されたすべてのフリースペースが記録されているファイルですので今は無視してOKです。

ですので、上記よりusersテーブルの実データサイズは16KBと分かりました。

以上です。もっと簡単に調べることができれば便利なのですが・・・。

ともあれ、この方法でDBの実データサイズを調べることができますので、ぜひご活用ください。

AWS Management ConsoleからAmazon EC2のインスタンスをセットアップしてみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

前回に引き続きAWSの記事です。

今回はAmazon EC2のインスタンスをセットアップする手順を紹介します。

※注意:ブラウザはFirefoxを推奨。理由は後述

まずは前回の記事で作成したAWSのアカウントを用意しましょう。

アマゾンウェブサービス(AWS)のアカウントを作成してみました。

1.アマゾンウェブサービスTOPにアクセス

http://aws.amazon.com/jp/

2.ページ右上の「アカウント/コンソール」⇒「AWS Management Console」をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.02.AWS_TOP_menu.png

画像の赤枠のリンクです。

3.作成したAWSアカウントでAWS Management Console Homeにログイン

http://doruby.kbmj.com/honda_on_rails/files/ec2.03.Amazon_Web_Services_Sign_In.png

“My e-mail address is:”にメールアドレスを、

“I am a returning user and my password is:”にチェックしてパスワードを入力し

「Sign in using our secure server」をクリック。

ログインに成功すると、↓のようなページに遷移します。

http://doruby.kbmj.com/honda_on_rails/files/ec2.04.AWS_Management_Console_Home.png

4.EC2 Management Consoleに移動

Amazon Web Servicesのメニューの中にある”EC2″をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.04.AWS_Management_Console_Home_EC2_link.png

画像の赤枠のリンクです。

以下のページに遷移します。

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console.png

5.インスタンスセットアップ開始

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console2.png

Regionが”Asia Pacific (Tokyo)”になっている事を確認(画像左上の緑枠)し、

画像中央の赤枠の”Launch Instance”をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.05.Create_a_New_Instance.png

Classic Wizardを選択して「Continue」をクリック

6.OSを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.06.Choose_an_ami.png

特に決めているものが無ければ”Amazon Linux AMI”の64bitを選択

インスタンスのタイプ次第ではメモリが4GBを超えるものもあるため、64bitを選択しておくのが無難だと思います。

7.インスタンスタイプを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.07.Instance_Type.png

言い換えればサーバースペックの選択ですね。

業務の場合は用途に合ったスペックのインスタンスタイプを選択してください。

今回は、無料で使用出来るMicroを選択しています。

8.Availability Zoneを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.08.Availability_Zone.png

特に決めていない場合は”No Preference”を選択で良いです。

ただし、webサーバー用インスタンスを複数台用意する等、冗長化構成を取る場合は予め使用するAvailability Zoneを決めておき、

明示的に”ap-northeast-1a”、”ap-northeast-1b”を選択するようにしてください。

http://doruby.kbmj.com/honda_on_rails/files/ec2.09.Advanced_Instance_Options.png
http://doruby.kbmj.com/honda_on_rails/files/ec2.10.Storage_Device_Configuration.png

途中のAdvanced Instance OptionsやStorage Device Configurationはそのままで次へ。

Shutdown Behaviorが”Stop”になっている事だけ確認しておいてください。

9.サーバー名を設定

http://doruby.kbmj.com/honda_on_rails/files/ec2.11.Add_tags_to_your_instance.png

これはインスタンス一覧に表示する際に使われるタグの設定です。

Nameのvalueにサーバー名を入れておきましょう。

10.鍵ファイルの作成&設定

ログインするのに必要な鍵ファイルを作成する

http://doruby.kbmj.com/honda_on_rails/files/ec2.18.Create_a_new_Key_Pair.png

“Enter a name for your key pair”のフォームに名前を入力して”Create & Download your Key Pair”をクリックする。

すると鍵ファイルのダウンロードが始まるので任意の場所に保存。

保存後は次の画面に自動で遷移します。

※なお、IEだとダウンロードに失敗するという情報があるので、firefoxで実施する

既存の鍵ファイルを流用する際は”Choose from your existing Key Pairs”から鍵ファイル名を選択する

11.セキュリティグループの作成&指定

外部からのアクセスを制限するため、IPアドレスやポートの設定を行う。

http://doruby.kbmj.com/honda_on_rails/files/ec2.12.Create_a_new_security_group.png

デフォルトでSSHの22番ポートが全IPアドレスに対して開放されている状態です。

http://doruby.kbmj.com/honda_on_rails/files/ec2.13.Create_a_new_security_group_list.png

HTTPやHTTPS等の良く使われる設定は、いちいち番号を入力せずともリストから選択可能です。

設定して「Continue」をクリック

12.確認画面の内容をチェック

http://doruby.kbmj.com/honda_on_rails/files/ec2.14.review_the_information.png

問題なければ”Launch”をクリックしてインスタンス起動

http://doruby.kbmj.com/honda_on_rails/files/ec2.15.Your_instances_are_now_launching.png

正常に起動されれば↑のような画面に遷移します。

以上の手順でインスタンスを起動する事が出来ました。

それでは最後に接続確認をしましょう。

13.作成したインスタンスにSSHでログイン出来る事を確認

EC2 Management Consoleからインスタンス一覧に遷移する

“INSTANCES”⇒”Instances”をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console_2.png

画像の赤枠のリンクです

インスタンス一覧に作成したインスタンスが追加されている事を確認し、クリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.16.EC2_Instance_selected.png

インスタンス詳細に大きくPublic DNSが表示されているので、メモしておく

画像の赤枠の部分です。

14.SSHクライアントでログイン

13で確認したPublic DNSと、10で作成した鍵ファイルを元にSSH接続

※SSHクライアントにputtyを使用している場合は、別途変換する必要有

ID: ec2-user

PASS: なし

でログイン出来る事が確認できればOKです。

あとがき

今回は手順を細かく砕いて説明したため、14もの工程になりましたが、手順そのものはさほど難しくなく

行う事が出来たのではないかと思います。

次回はEC2を業務利用する上で必要な作業の1つであるEIPの設定手順を紹介したいと思います。

rails3のログ解析ツール「request-log-analyzer」について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rails3のログ解析ツールを紹介します。

 request-log-analyzer

rails3のproduction.logを解析する事になったので、調べてみると

request-log-analyzerというツールが良いとの記事を見た。

 インストールしてみる。

railsが入っている環境であれば以下のコマンドでインストールされます。

 gem install request-log-analyzer

 小職の環境では、以下にインストールされました。

/usr/local/bin/request-log-analyzer

 使ってみる

以下を入力すると。。。。

request-log-analyzer production.log

解析が始まり、解析が終わると

Request summary リクエストのサマリー
  • Parsed lines 解析した行数
  • Skipped lines スキップした行数
  • Parsed request 解析したリクエスト
  • Skipped lines スキップしたリクエスト
  • Warnings 警告数
  • First request 最初のリクエストの日時
  • Last reuquest 最後のリクエストの日時
  • Total time analyzed 解析した期間
Request distribution per hour 時間当たりのリクエスト数
Most requested リクエストの多い順(TOP20)
HTTP methods HTTPメソッド毎のリクエスト数
HTTP status returned HTTPのステータス毎のリクエスト数
REQUEST DURATION – BY SUM リクエストの所要時間の合計
REQUEST DURATION – BY MEAN リクエストの所要時間の平均
VIEW RENDERING TIME – BY SUM ビューのレンダリング時間の合計
VIEW RENDERING TIME – BY MEAN ビューのレンダリング時間の平均
DATABASE TIME – BY SUM データベースからの応答時間の合計
DATABASE TIME – BY MEAN データベースからの応答時間の平均
Process blockers (> 1 sec duration) 
Parse warnings 解析時のワーニングが表示されます

 railsのログ以外での使い方

Apacheのログを解析したい。

request-log-analyzer apache.log

rails ログと同様に解析した結果が出力されます。

 さまざまなオプション

入力オプション

–format, -f 解析するログのフォーマットを指定します。

  rails,rails3 rails のログとして解析します。

  apache apacheのログとして解析します。

  この他にも、merb,rack,delayed_job,amazon_s3,mysql,postgresql,oink,haproxy等を解析できるようです。

出力オプション

–output , -o 出力するフォーマットを指定します。

デフォルトだとコンソールに整形された文字列として出力されます。

   HTML HTML形式で整形された文字列として出力されます。

–file 指定したファイルに出力します。

–database,-d 指定したSQLite3形式のデータベースとして出力します。

詳しくは以下に載っています。あなたもこれでログ解析ライフを!

https://github.com/wvanbergen/request-log-analyzer/wiki

アマゾンウェブサービス(AWS)のアカウントを作成してみました。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。KBMJ改めアピリッツの本多です。

最近仕事で利用しているAWSについての記事を書かせて頂きます。
今回は、アカウントの作成手順を紹介します。

■予め必要なもの

・クレジットカード
・有効な電話番号
・メールアドレス

1.アマゾンウェブサービスTOPにアクセス

http://aws.amazon.com/jp/

2.ページ右の「今すぐ申し込む」または右上の「サインアップ」をクリック


画像の赤枠のリンクです。

3.ログイン用のメールアドレスを入力してサインアップを開始


My e-mail address isの欄に自身のメールアドレスを入力し、
I am a new user.をチェックして「Sign in using our secure server」をクリック。

4.ログイン用の情報を登録


アカウント名及びログインするためのメールアドレス/パスワードを入力して「Continue」をクリック
My e-mail address isの欄には、先ほど入力したメールアドレスが予め入っている状態です。

5.利用者の個人情報の登録


お問い合わせ情報のフォームに住所、氏名、電話番号等を入力し、
利用規約に同意して「アカウントを作成して続行」をクリック。
注意点としては、氏名や住所等の情報が全て半角英数字で入力しなければならないという事です。
例えば“渋谷区”⇒”Shibuya-ku”みたいな書き方をしないといけないので、慣れない入力に戸惑うかもしれません。

6.クレジットカードの情報を登録


クレジットカードの情報を入力して「続ける」をクリック
請求先は5で登録した住所をそのまま指定する事ができます。

7.電話による身元確認を実施

なんと、AWSから実際に電話を受けて認証を行うシステムが導入されています。
おそらく一個人・団体がアカウントを大量に取得する事を防ぐための対策だと思いますが、ここまでやるかAmazonと関心しました。


国コードは”Japan(+81)”を選択し、電話番号(必要な場合は内線番号も)を入力して「確認用に自分に電話をする」をクリック。


しばらくするとAWSから電話がかかってくるので、案内にしたがって画面に表示されている暗証番号を通知する。


暗証番号の通知に成功すると、画面が↑のように切り替わって身元確認が完了します。
「続ける」をクリック。

8.確認画面に遷移し、AWS側の認証を待つ


認証が完了したら登録したメールアドレス宛に

「AWS Unified Registration Sign-Up Confirmation」

というタイトルで登録完了メールが送られてきます。
メールが届けば、AWSが利用可能になります。

あとがき

以上の手順で、AWSへのアカウント登録が完了しました。
英語での住所の入力や、電話を使っての身元確認はあまり他で見かけないため戸惑うかもしれませんが、
難しくは無いので頑張って挑戦してみてください。

次回は作成したアカウントを使って、Amazon EC2 Instanceの作成手順を紹介したいと思います。

Mysql(InnoDB)のロックの変化について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近、MysqlでUpdate を行った際、更新対象件数によって、書き込みロックが行ロックからテーブルロックに変化することがあったので

その原因と対処方法について書こうと思います。

環境は下記の通りです。

OS: CentOS 5.6, MacOSX 10.7.3
Mysql 5.1(InnoDB)

↓のテーブルに、1000件レコードが存在すると仮定して説明していきます。

CREATE TABLE `sample_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ロックが行ロックからテーブルロックに変化する現象が発生するのは、

以下のSQL文です。

UPDATE sample_table SET val = "hoge" WHERE id in (100件分のid); => 行ロック
UPDATE sample_table SET val = "hoge" WHERE id in (500件分のid); => テーブルロック

ロックの変化の原因を探っていると、EXPLAINの結果に違いがあることがわかりました。

対象件数が100件の場合にはtypeがrangeなのに対し

対象件数が500件の場合にはtypeがALLになり、インデックスが使われていません。

対象件数 100件
EXPLAIN SELECT * FROM sample_table WHERE id IN (100件分のid);
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table            | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | products         | range | PRIMARY       | PRIMARY | 4       | NULL |  500 | Using where |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+

対象件数 500件
EXPLAIN SELECT * FROM sample_table WHERE id IN (500件分のid);
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table            | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | products         | ALL  | PRIMARY       | NULL | NULL    | NULL | 1000 | Using where |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+

このフルテーブルスキャンが原因でテーブルロックが発生していました。

ロックの変化についてMysqlリファレンスを調べたところ、下記のような記述がありました。

 MySQL では利用可能な場合でもインデックスが使用されない場合があることに注意し
てください。この一例として、インデックスの使用によって、MySQL がテーブルの 30% 
を超えるレコードにアクセスする必要が生じる場合が挙げられます(この場合は、必要な
シークが大幅に減少するため、テーブルスキャンのほうが高速になる可能性が高くなり
ます)。 ただしこのクエリに、レコードの一部のみを取り出す LIMITが使用されている場
合、結果で返される少数のレコードを迅速に検索できるため、MySQL はインデックスを
使用します。

上記を参考に、LIMITを付け加えることでインデックスが使用され、テーブルロックになることが防げました。しかし、速度が犠牲になる可能性があるため、使いどころは考える必要がありそうです。

最近人気な記事