狛ログ

2016年11月13日日曜日

MySQLの timestamp型が、なかなか厄介。

11月 13, 2016
オフィス狛 技術部です。

弊社ではしばらく使う事のなかったMySQLですが、
とあるプロジェクトで久しぶりに使い、そしてハマりました。

問題となったテーブル

まず、以下のようなCreate文を実行しました。
CREATE TABLE koma_test (
      koma_test_id bigint NOT NULL AUTO_INCREMENT,
      koam_code varchar(2) NOT NULL,
      test_count int,
      test_fee decimal(7,0),
      has_deleted boolean DEFAULT false NOT NULL,
      entry_datetime timestamp NOT NULL,
      entry_user varchar(100),
      update_datetime timestamp NOT NULL,
      update_user varchar(100),
      PRIMARY KEY (koma_test_id)
);

entry_datetime」「update_datetime」などは、システムで良くあるタイムスタンプ系のカラムです。
日時はプログラム側で設定する事を想定しています。

発生した現象

本来、プログラム側では登録時(Insert時)のみ「entry_datetime」が設定され、
それ以降、その値は変わらない想定でした。

ところが、テーブル更新時(Update時)に「entry_datetime」が勝手に更新されていたのです。
当然最初はプログラムを疑いましたが、プログラムに問題はありませんでした。

で、ちょっとハマった後、何気なく作成されたテーブルの定義を確認すると、
「entry_datetime」に「CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」が付いているのです。
(「update_datetime」には付いていない)

もちろん、Create文には、そのような指定はしていません。
どうやら、timestamp型には、デフォルトで「CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」が付いてしまうようです。
※他のサイトの情報だと、NULL 許可していても、NOT NULL にもなってしまうようです。

なんて余計なお世話だ・・・とも思いましたが、
まあ、「timestamp」という属性名だし、そういう事になりますよね・・・
タイムスタンプ系の使い道で無い場合、型は「datetime」にすれば良いだけですからね。

とは言うものの、今のままでは、本来の用途に使えないので、テーブルの定義を変更します。
ALTER TABLE koma_test CHANGE entry_datetime entry_datetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

注意事項ですが、デフォルト値の「CURRENT_TIMESTAMP」も削除したいからといって、
ALTER TABLE koma_test CHANGE entry_datetime entry_datetime TIMESTAMP NOT NULL;
というSQLを流してしまうと、
またデフォルトの「CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」が付いてしまいます。

MySQLを使い込んでいる方ですと、「そりゃ、そうでしょ」レベルの話なのかもしれませんが、
久しぶりに使うと、ハマってしまいますね。


2016年11月7日月曜日

Raspberry Pi 3 で 3G 通信をしてみる。 〜 Raspberry Pi 3 への 3GPI 取付と設定 〜

11月 07, 2016
オフィス狛 技術部です。

Raspberry Pi で 3G 通信をしてみよう! という事で、
今回は、Raspberry Pi と 3GPIの取り付けを行なっていきます。

・SIMカード準備

SIMはカードのような物に付いているので、丁寧に取り外します。


外したSIMを変換アダプタ(標準SIM)へセットします。
今回は、汎用性を考えて(この検証以外でも使いたいので)、
nano(ナノ)サイズSIMを購入しましたが、標準SIMサイズを購入していれば、上記作業は不要です。
※SORACOMでは、ナノ、マイクロ、標準SIMのサイズが用意されています。

・3GPI同梱品確認

実際の作業の前に、3GPIの同梱品を確認します。

【同梱品一覧】(取扱説明書より)
  • 3GPI本体 1枚
  • 接続設定済Raspbian入microSDカード(SD用アダプタ付) 1枚
  • 3Gアンテナ 1本
  • ACアダプタ(12V 1A) 1個
  • USB-A雄-USBmini-b雄 100mmケーブル 1本
  • Raspberry Pi ModelB+用六角スペーサ(M2.6)セット 2セット

・Raspberry Pi に 3GPI を取り付ける

では、Raspberry Pi に3GPIをセットしたいと思います。
まずは写真の赤枠の部分に、六角スペーサを取り付けます。


こんな感じです。
ナットで裏側から固定しています。


裏側はこんな感じです。


続いて、Raspberry Pi のGPIOピンに、3GPIを差し込みます。
結構強めに押し込まないとちゃんとハマりませんが、
繊細なので、壊さないように力込めましょう。
GPIOピンに差し込んだ後に、六角スペーサのネジを締めます。
写真の赤枠がネジを締めた後の状態です。

・SDカード取付

本体をひっくり返して、microSDカードを差し込みます。
※microSDカードの裏表を間違えないように。

・SIMカード取付

SIMスロットは閉じている状態の時に、奥に押す感じでずらすと開きます。
IC端子と切れている部分の位置に気を付けてセットします。


スロットを閉じた後は、先程と逆に手前に引く感じでずらすと、固定されます。

・その他取付

3Gアンテナを取り付けます。端子が二つありますので、
"RF"と記載されている方に取り付けます。
結構力を入れないとネジが回りませんので、壊さないように力込めましょう。


Raspberry Pi のUSBと、3GPIのUSBmini-Bを繋ぎます。


後は電源投入ですが、その前に、
Raspberry Pi にUSBキーボードと、HDMIケーブルを接続しています。


最後に3GPI側に電源を接続します。


起動しました。
3GPIが梱包されていた箱の内側に、UserNameとPasswordが記載されているので、
入力してログインします。

・SSH接続設定

Raspberry Pi へTeraTermなどで接続する為の設定を行います。
コンソール上で「sudo raspi-config」とコマンドを打ちます。

起動した設定画面で「9 Advanced Options」を選択します。


次に出てきた画面で「A4 SSH」を選択します。


SSH Serverを有効(Enable)にします。


セットアップはここまでとなります。
写真がセットアップ後の状態です。(LANケーブルも接続しています)
大きさの比較に、フリスクも置いてみました。

※SORACOMは(と言うより、データ通信のみのSIMはほとんど)、
グローバルIPではなくプライベートIPが割り振られます。
その為、SIMの接続を利用したリモート接続が出来ません。
(中継サーバーを設ける事で可能になるようですが、今回は記載しません)
という事で、リモート接続をする為に、LANケーブルを接続しています。


さて、3G通信の準備が完了したので、次は実際に通信速度を測ってみようと思います。

3)通信速度を測ってみる(近日公開予定)


2016年11月1日火曜日

Raspberry Pi 3 で 3G 通信をしてみる。〜 SORACOM アカウント登録から SIM 登録まで 〜

11月 01, 2016
オフィス狛 技術部です。

Raspberry Pi で 3G 通信をしてみよう! という事で、
まずは、3G通信を行う為のSIMの準備を行います。

・SIMの購入

今回購入した SIM は「SORACOM Air SIM カード(データ通信のみ) (ナノ)」となります。
SORACOM のサイトから購入する事も可能ですが、今回は、即日納品可能な Amazonで購入しました。

・SORACOMアカウント登録〜ログイン

SIMが用意出来たら、SORACOM社 のサイト(https://soracom.jp/)にてアカウント登録を行います。

アカウント登録後、ログインすると、以下のような画面が表示されます。
まだ SIM は何も登録されていない状態です。

・SIMの登録

「+SIM 登録」押すと、SIM の情報を入力するポップアップが表示されます。
IMSI・パスコードは、購入した SIM が取り付けてあるカードの後ろに記載してあります。

登録すると、先程の SIM の一覧に表示されます。

・通信料金

SORACOM社のサイト(ご利用料金 - 日本向け Air SIM)を見てもらうのが一番ですが、
注意すべき点は、「SIMを登録した時点から料金が発生する」という事です。
今回は、データ通信のみのSIMを登録したので、登録直後から、「1日5円」が発生します。 そして、実際に使い始めると、「1日10円」の基本料金+通信料が発生します。
(ま、それでもSORACOMは、かなりお安いと思います。)

さらに、使用する時間帯や、通信速度によっても料金が変わってくるので、気をつけましょう。

さて、SIMの準備が完了したので、次はRaspberry Pi 3 への 3GPI 取付と設定になります。


2)Raspberry Pi 3 への 3GPI 取付と設定
http://blog.officekoma.co.jp/2016/11/raspberry-pi-3-3g-raspberry-pi-3-3gpi.html

2016年10月31日月曜日

Raspberry Pi 3 で 3G 通信をしてみる。

10月 31, 2016
オフィス狛 技術部です。

Raspberry Pi で 3G 通信をしてみよう! という事で、
4ヶ月ほど前に色々検証したのですが、ブログに載せるのが遅れてしまいました。

検証に使用したのは、「3GPi」という通信モジュールですが、
検証内容をブログに載せるのが遅れている間に、「3GPi」の販売元の会社から、
「anyPi(エニーパイ)」というスターターキットが出てしまいました。

約3分でセットアップできる! ラズパイIoT向けスターターキット 「anyPi」

ホント、IT業界ってのは時の流れが早いです。
しかし、ブログに載せるのを遅れた自分への戒めの為、今このタイミングで敢えて、
上記スターターキットを使わない方法を載せたいと思います。

大まかな手順は以下の通りです。

1)SORACOM アカウント登録から SIM 登録まで

2)Raspberry Pi 3 への 3GPI 取付と設定

3)通信設定&通信速度を測ってみる


今回、実験するのに用意したのは、以下の機器です。

  • SORACOM Air SIM カード(データ通信のみ) (ナノ)
  • Raspberry Pi 3 Model B (Element14)
  • REMAX SIM 変換 アダプター 4 点セット ナノシム
  • 3GPI(Raspberry Pi 向け 3G 通信モジュール)

そして、またもや言い訳になってしまいますが、載せる情報は、少し古い可能性がありますので、
最新の情報は、各メーカーのホームページ等を参照して頂くようお願いします。

では早速、最初の手順を進めて行きます。

1)SORACOM アカウント登録から SIM 登録まで
http://blog.officekoma.co.jp/2016/10/raspberry-pi-3-3g-soracom-sim.html


2016年10月30日日曜日

SwiftにおけるUIImageView・contentMode 別の画像表示

10月 30, 2016


オフィス狛 技術部です。

実装をしていると「あれ?これどうやるんだっけ?」
ということが人並み以上に多いため、
よく忘れるあれなものをどんどんメモします。

今回は、SwiftでUIImageViewmにImageを設定するときのcontentModeの表示方法
※画像は320 x 600 の縦長の画像を使い、300 x 300のImageViewの中に表示するようにしています。


1) サイズ指定無し(アスペクト比維持)の画像



2) ScaleToFill = 縦横の比率を変えて全体を表示する
imageView.contentMode = UIViewContentMode.ScaleToFill




3) Aspect Fit = 縦横の比率はそのままで長い辺を基準に全体を表示する
imageView.contentMode = UIViewContentMode.ScaleAspectFit




4) Aspect Fill = 縦横の比率はそのままで短い辺を基準に全体を表示する
imageView.contentMode = UIViewContentMode.ScaleAspectFill




5) Redraw = Aspect Fillとの違いはUIImageViewのサイズ変更に追随してリサイズしてくれる。
imageView.contentMode = UIViewContentMode.Redraw




6) Center = 画像サイズを変えずに真ん中を基準にして表示する
imageView.contentMode = UIViewContentMode.Center




7) Top = 画像サイズを変えずに上辺を基準にして表示する
imageView.contentMode = UIViewContentMode.Center




8) Bottom = 画像サイズを変えずに下辺を基準にして表示する
imageView.contentMode = UIViewContentMode.Bottom




9) Left = 画像サイズを変えずに左辺を基準にして表示する
imageView.contentMode = UIViewContentMode.Left




10) Right = 画像サイズを変えずに右辺を基準にして表示する
imageView.contentMode = UIViewContentMode.Right




11) Top Left = 画像サイズを変えずに左上を基準にして表示する
imageView.contentMode = UIViewContentMode.TopLeft




12) Top Right = 画像サイズを変えずに右上を基準にして表示する
imageView.contentMode = UIViewContentMode.TopRight




13) Bottom Left = 画像サイズを変えずに左下を基準にして表示する
imageView.contentMode = UIViewContentMode.BottomLeft




14) Bottom Right = 画像サイズを変えずに右下を基準にして表示する
imageView.contentMode = UIViewContentMode.BottomRight




以上、ほとんど自分の為の備忘録です。はい。


2016年9月11日日曜日

知らねばほっとけとはいかない Codeigniter3 独自 バリデーション チェック に 引数 を渡す

9月 11, 2016


オフィス狛 技術部です。

第1回(小石につまずくとけっこう痛い Codeigniter3 ファイル命名規約)、
第2回(小石につまずくとけっこう痛い Codeigniter3 複数ファイル同時アップロード)、
第3回(小石につまずくとけっこう痛い Codeigniter3 csrf_token の 有効期限切れ エラー をキャッチ)に引き続き、

今回も PHP ( Codeigniter3 )で地味につまずいたことと書こうと思っております。
今回は、
『 独自のバリデーションチェック に引数を渡す 』
です。

独自バリデーションチェックの作成方法は本家サイトにお任せします。
Form Validation — CodeIgniter 3.1.0 documentation callbacks-your-own-validation-methods

ちなみに
 $this->form_validation->set_rules() に設定する際に
メソッドの先頭に「 callback_ 」を付けなければいけないというルールを知らずに
ちょっとつまってしまった経験があるので、一応記載しておきます。
チェックメソッドが
username_check()
ならば、
$this->form_validation->set_rules('username', 'Username', 'callback_username_check');
と書く必要があるということですね。

では、このチェックメソッドにどうやって引数を渡すのか?

調べた結果、2つ方法があるようです。
1.  $this->input->post() で取得する
$this->form_validation->set_rules('uri', 'URI', 'callback_check_uri');
function check_uri(){
 $this->input->post('url');
 $this->input->post('id');
}

2. $this->form_validation->set_rules()の中に書く
$this->form_validation->set_rules('uri', 'URI', 'callback_check_uri['.$this->input->post('id').']');
function check_uri($field, $id){
 // $fieldにはバリデーション対象のPOSTデータが自動で入ります。
}
※CI2.1以上であることが条件だそうです。

個人的には
文字列結合して引数を渡しているのが
どうしても無理やりな感じがしているので
1の方がいいなと思うのですが
公式ドキュメントでは2の方法が書かれています。

1の場合ですと、引数が増えても楽に対応出来そうですよね。

ちなみに2のような形式で行う場合は、

$this->form_validation->set_rules('uri','URI','callback_check_uri[id,method]');
function check_picture($image,$param){
 $param = preg_split('/,/', $param);
 $id = $param[0];
 $method = $param[1];
}
と書けば上手くいくようです。
※公式ではないようですが。。。

チェック自体は単純にPOSTデータを取得してチェックが可能ですが、
その後のエラーメッセージの表示などを考えると他のバリデーションチェックと
同じようにできるのは便利ですし、可読性・保守性が向上するのではないかと思います。

知らねばほっとけではいけませんね。

2016年9月2日金曜日

小石につまずくとけっこう痛い Codeigniter3 csrf_token の 有効期限切れ エラー をキャッチ

9月 02, 2016
オフィス狛 技術部です。

前々回(小石につまずくとけっこう痛い Codeigniter3 ファイル命名規約)、
前回(小石につまずくとけっこう痛い Codeigniter3 複数ファイル同時アップロード)に引き続き、

今回も PHP ( Codeigniter3 )で地味につまずいたことと書こうと思っております。

何度も言いますが
 Codeigniter は日本語の情報が少ない!!!
ということでよくつまずきます。

なので、自分の調べた備忘録も兼ねて、
ここにつまずきろく(記録)をためていきたいと思います。

今回のつまずきは、
『 csrf_token の有効期限切れ エラーをキャッチする 』
でした。

デフォルトの設定ですと「 error_general.html 」が表示されるようになっていますが、
弊社では、「操作に失敗しました。」といったようなその名の通り全般的なエラーの内容を表示するようにしています。

画面を放置していて動かしてみたらいきなり「操作に失敗しました。」と出るのは違和感があるので、そのままページを再読み込するようにしてほしいとの要望がありました。

どうやるのかパッと思いつかず、つまずき発生。
で、色々調べてみた結果、

「 CI_Security 」を継承して「 csrf_show_error() 」メソッドをオーバーライドすればよかったようです。

class MY_Security extends CI_Security {
    public function __construct()
    {
        parent::__construct();
    }
    public function csrf_show_error()
    {
        // エラー画面を表示したり
        // show_error('The action you have requested is not allowed.');

        // ページをリフレッシュしたり
        // header('Location: ' . htmlspecialchars($_SERVER['REQUEST_URI']));
    }
} 
参考にしたサイト:
http://stackoverflow.com/questions/14406922/prevent-from-displaying-the-default-csrf-error-page-in-codeigniter

そういえば、独自のエラーハンドリングを行う際も、
「 CI_Exceptions 」を継承してエラーメソッドをオーバーライドするのと同じだなと後々気が付きました。

パッと出てこないということはまだまだ習熟が足りてない証拠です。
改めてドキュメントを見返してみるなど勉強が必要だなと思う今日この頃でした。

足元の確認は大事ですね。