OmniAICreator/Qiita-1.07M huggingface dataset:
CasperJSをCentOS 5/6にインストール

# CasperJSをCentOS 5/6にインストール

## 概要

ヘッドレスブラウザPhantomJSを使ってJavascriptでテスト/スクレイピングができるCasperJSをCentOS 5/6にインストールします。Node.jsは不要です。

http://casperjs.org/

## インストール

rootで以下の作業を行います。

````shell
yum -y install fontconfig freetype libstdc++
cd
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.8-linux-x86_64.tar.bz2 -O phantomjs-1.9.8-linux-x86_64.tar.bz2
wget https://github.com/n1k0/casperjs/tarball/1.0.3 -O casperjs-1.0.3.tar.gz
cd /opt
tar jxvf ~/phantomjs-1.9.8-linux-x86_64.tar.bz2
mv phantomjs-1.9.8-linux-x86_64 phantomjs-1.9.8
tar zxvf ~/casperjs-1.0.3.tar.gz
mv n1k0-casperjs-76fc831 casperjs-1.0.3
cat << EOT >/etc/profile.d/casperjs.sh
export PATH=/opt/casperjs-1.0.3/bin:/opt/phantomjs-1.9.8/bin:\${PATH}
EOT
````

CentOS5のみ追加で以下の作業を行います。

````shell
yum install python26
cat << EOT >>/etc/profile.d/casperjs.sh
alias casperjs='python26 /opt/casperjs-1.0.3/bin/casperjs'
EOT
````

(オプション)スクリーンキャプチャで日本語を表示するにはフォントのインストールと設定を行います。rootで以下をインストールします。

````shell
yum -y install ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts
````

ユーザ毎に~/fonts.confを以下の内容で作成します。

````xml
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">

<fontconfig>
  <alias>
    <family>serif</family>
    <prefer>
      <family>IPAP Mincho</family>
    </prefer>
  </alias>

  <alias>
    <family>sans serif</family>
    <prefer>
      <family>IPAP Gothic</family>
    </prefer>
  </alias>

  <alias>
    <family>sans-serif</family>
    <prefer>
      <family>IPAP Gothic</family>
    </prefer>
  </alias>

  <alias>
    <family>monospace</family>
    <prefer>
      <family>IPA Gothic</family>
    </prefer>
  </alias>
</fontconfig>
````

ユーザ毎にフォントキャッシュをクリアします。

````shell
fc-cache -fv
````

##サンプル

### サンプル1

以下の内容でsample.jsを作成します。

````javascript
var casper = require('casper').create();

casper.start('http://fusic.co.jp/', function() {
    this.echo(this.getTitle());
});

casper.run();
````

以下のコマンドで実行します。

````shell
casperjs sample.js
````

### サンプル2(DOMの取得)

以下の内容でsample2.jsを作成します。

````javascript
var casper = require('casper').create();

casper.start('http://fusic.co.jp/', function() {
    var text = this.evaluate(function() {
      return __utils__.findOne('meta[name="keywords"]').content;
    });
    this.echo(text);
});

casper.run();
````

以下のコマンドで実行します。

````shell
casperjs sample2.js
````

### サンプル3(スクリーンキャプチャ)

フォントのインストールと設定を行ってから、以下の内容でsample3.jsを作成します。

````javascript
var casper = require('casper').create({
    viewportSize: {
        width: 1024,
        height: 768
    }
});

casper.start('http://fusic.co.jp/', function() {
    this.capture('fusic.png');
});

casper.run();
````

CentOS6は以下のコマンドで実行します。

````shell
env LANG=C casperjs sample3.js
````

CentOS5は以下のコマンドで実行します。

````shell
env LANG=C python26 /opt/casperjs-1.0.3/bin/casperjs sample3.js
````

## 参考にした情報

公式ドキュメントにCoffeeScript版やテストのことが書いてあります。また、jQueryを使うこともできるようです。

http://docs.casperjs.org/en/latest/quickstart.html

その他に参考にした記事です。

* casperJSでwebスクレイピング | THE SPORTS BUSINESS
 * http://thesportsbusiness.jp/archives/189
* お手軽！CasperJSとJenkinsでサイトの自動テスト - Catcher in the tech
 * http://catcher-in-the-tech.net/1456/
PostgreSQLでストアドプロシージャを一括ドロップする方法

# PostgreSQLでストアドプロシージャを一括ドロップする方法

````sql
-- PostgreSQL 9.2で動作確認しました
-- 前提:sp_drop_function_allという名前のストアドプロシージャはないと仮定
CREATE OR REPLACE FUNCTION sp_drop_function_all(
) RETURNS int AS $$
DECLARE
  cur refcursor;
  sql_text text;
BEGIN
  OPEN cur FOR
    SELECT
      'DROP FUNCTION IF EXISTS ' || p.proname || '(' || pg_catalog.oidvectortypes(p.proargtypes) || ');'
    FROM
      pg_catalog.pg_proc AS p
    LEFT JOIN
      pg_catalog.pg_namespace AS n
    ON
      n.oid = p.pronamespace
    WHERE
        p.prorettype <> 'pg_catalog.cstring'::pg_catalog.regtype
      AND
        (
          p.proargtypes[0] IS NULL
        OR
          p.proargtypes[0] <> 'pg_catalog.cstring'::pg_catalog.regtype
        )
      AND
        NOT p.proisagg
      AND
        n.nspname = 'public'
      AND
        pg_catalog.pg_function_is_visible(p.oid)
      AND
        p.proname != 'sp_drop_function_all'
  ;
  LOOP
    FETCH NEXT FROM
      cur
    INTO
      sql_text
    ;
    IF NOT FOUND THEN
      EXIT;
    END IF;
    --RAISE NOTICE '%', sql_text;
    EXECUTE sql_text;
  END LOOP;
  CLOSE cur;
  RETURN 0;
END;
$$ LANGUAGE plpgsql;

SELECT * FROM sp_drop_function_all();

DROP FUNCTION IF EXISTS sp_drop_function_all();

````
CakePHPからPostgreSQLのpsqlコマンドを実行する方法

# CakePHPからPostgreSQLのpsqlコマンドを実行する方法

やんごとなき事情でCakePHPからPostgreSQLのpsqlコマンドを実行する場合は以下のようにします。

```php
App::uses('ConnectionManager', 'Model');

// DBの設定情報を取得
$db = ConnectionManager::getDataSource('default');

// 実行するコマンドラインを構築
$cmd = '';
$cmd .= ' env PGPASSWORD=' . $db->config['password'];
$cmd .= ' psql';
$cmd .= ' -U ' . $db->config['login'];
$cmd .= ' -h ' . $db->config['host'];
$cmd .= ' -p ' . $db->config['port'];
$cmd .= ' -d ' . $db->config['database'];
$cmd .= ' -c "SQL文"';

exec($cmd, $output, $return_var);
```
corosyncのIncrementing problem counterのログについて

#現象
MLでも回答したのですが、corsoync2.3.4でクラスタを構成(rrp_mode:active)している場合に、たまに、以下のようなログが出る（頻繁に出る）場合があります。

```message.log

Incrementing problem counter for seqid 9999 iface xxx.xxx.xxx.xxx to [1 of 10]
(snip)
Incrementing problem counter for seqid 9999 iface xxx.xxx.xxx.xxx to [1 of 10]

```

#原因
corosyncのrrp_mode:activeでは、corosyncの通信インターフェースに対して、両方に同じデータを送信する方法を取ります。
このデータはノード間を巡回するのですが、rrp_mode:activeの場合、受信ノード側が両方のデータの到着を監視しています。

片方のデータの受信後、一定時間(デフォルトでは、corosync.confのtoken値/4.2)、もう片方のインターフェースから受信が無い場合に、このログが出力されます。
（この一定時間内に両方のインターフェースで受信している間は、ログは出ない）

```totemsrp.c
(snip)
static void timer_function_active_token_expired (void *context)
{
	struct active_instance *active_instance = (struct active_instance *)context;
	struct totemrrp_instance *rrp_instance = active_instance->rrp_instance;
	unsigned int i;

	for (i = 0; i < rrp_instance->interface_count; i++) {
		if (active_instance->last_token_recv[i] == 0) {
			active_instance->counter_problems[i] += 1;

			if (active_instance->timer_problem_decrementer == 0) {
				active_timer_problem_decrementer_start (active_instance);
			}
			snprintf (rrp_instance->status[i], STATUS_STR_LEN,
				"Incrementing problem counter for seqid %d iface %s to [%d of %d]",
				active_instance->last_token_seq,
				totemnet_iface_print (rrp_instance->net_handles[i]),
				active_instance->counter_problems[i],
				rrp_instance->totem_config->rrp_problem_count_threshold);
			log_printf (
				rrp_instance->totemrrp_log_level_warning,
				"%s",
				rrp_instance->status[i]);
		}
	}
(snip)
```

上記の場合、[10 of 10]まで達すると、そのインターフェースは故障と判断されますが、それまでは、自動的にこのカウンタをデクリメントしてくれる為、このログは通常は無視しても良いログです。
（環境のよっては、かなり頻繁に出てしまうので、うざい感じもありますが・・・）

#余談
rrp_mode:passiveの場合は交互にインターフェースを利用してデータをノード間で送受信する為、前述のログは出ません。
rrp_mode:noneの場合は、１つのインターフェース（ボンディングしていても）のみなので、前述のログは出ません。
PostgreSQLのPL/pgSQLのデバッガpldebuggerを使ってみる

# PostgreSQLのPL/pgSQLのデバッガpldebuggerを使ってみる

pldebuggerを使うとpgAdmin III上でPL/pgSQLのストアドプロシージャのデバッグができます。

http://git.postgresql.org/gitweb/?p=pldebugger.git;a=summary

## インストール

CentOS6+SCL+PostgreSQL 9.2向けのansible play bookはこちらになります。

https://github.com/sadapon2008/ansible-postgres92-pldbgapi-cent6

ざっくりこんな手順になってます。(rootで作業するものとします。)

### 1. PostgreSQLのヘッダファイル類をインストールします

````sh
yum install postgresql92-postgresql-devel
````

### 2. gitからcloneしてきます

````sh
git clone git://git.postgresql.org/git/pldebugger.git
````

### 3. Makefileを修正します

````sh
cd pldebugger
sed -i.bak -e "s/\$(top_builddir)\/src\/pl\/plpgsql\/src/\/opt\/rh\/postgresql92\/root\/usr\/include\/pgsql\/server/g" /root/pldebugger/Makefile
※ postgresql-develまたはPostgreSQLのヘッダファイル類が以下にあることを仮定しています
    /opt/rh/postgresql92/root/usr/include/pgsql/server
````

### 4. コンパイル＆インストールします

````sh
env USE_PGXS=1 make
env USE_PGXS=1 make install
````

### 5. postgresql.confを変更します

````sh
sed -i.bak -e "s/#shared_preload_libraries = ''/shared_preload_libraries = '\/opt\/rh\/postgresql92\/root\/usr\/lib64\/pgsql\/plugin_debugger.so'/" /opt/rh/postgresql92/root/var/lib/pgsql/data/postgresql.conf
````

### 6. PostgreSQLをリスタートします

````sh
service postgresql92-postgresql restart
````

## pgAdmin III上での初期設定

1. DBに接続します
2. 「Extensions」→「New Extension...」
3. 「名前」で「pldbgapi」を選択して「OK」
4. pgAdmin IIIを一度終了して再度起動してください

## pgAdmin III上でのデバッガの利用

1. DBに接続します
2. 「関数」からデバッグしたい関数を選択して右クリックメニューの「デバッグ」→「ブレークポイントの設定」
 * デバッガのウィンドウが開いてストアドプロシージャの先頭にブレークポイントが設定された状態になります
3. SQLクエリーからストアドプロシージャを実行
 * デバッガのウィンドウでブレークされた状態になります

## 注意点

* デバッガはやや不安定でpgAdmin IIIごと強制終了することがあります
* そのため、SQLクエリーで実行するSQL文はきちんとテキストファイルで保存しておくことをおすすめします
Ruby wrapper for Gitlab APIを使ってMerge requestのコメントを取得する

# Ruby wrapper for Gitlab APIを使ってMerge requestのコメントを取得する


## 動機

↓を使うとRubyでGitlabの情報がAPI経由で習得できます。

https://github.com/NARKOZ/gitlab

Rubyの対応バージョンは不明ですが、2.1.0p0で動作することを確認してます。

これを使ってGitlab上のMerge requestのコメントを取得してみたいと思います。

※Rubyについては初心者なので色々間違ってるかもしれません。

## インストール

rbenvだとこんな感じでいけました。

````
rbenv exec gem install gitlab --no-rdoc --no-ri
````

## サンプル

指定したプロジェクトの指定した番号のMerge requestのコメントを取得します。

````ruby
#!/usr/bin/ruby -W0

require 'gitlab'

# SSL証明書のチェックをしない
# 自己署名の証明書を使っている場合に必要です
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

# コマンドライン引数チェック
if ARGV.size < 2 then
  puts 'usage: ' + $0 + ' project_name merge_request_number'
  exit!
end

# プロジェクト名
target_project_name = ARGV[0]

# Merge requestの番号
target_merge_request_number = ARGV[1]

# Gitlabへの接続設定
Gitlab.configure do |config|
  config.endpoint       = 'https://(GitlabのURL)/api/v3'
  config.private_token  = '(Gitlabユーザのプライベートトークン)'
end

# 結果
target_description = ''
project_found_flg = false
found_flg = false

# プロジェクトを名前で探す
Gitlab.projects.each do |project|
  project_name = project.name
  if project_name == target_project_name then
    project_found_flg = true
    # Merge requestを番号で探す
    page = 0
    begin
      count = 0
      page += 1
      Gitlab.merge_requests(project.id ,:page => page, :per_page => 100).each do |mr|
        count += 1
        if mr.iid.to_i == target_merge_request_number.to_i then
          found_flg = true
          target_description = mr.description
          break
        end
      end
      break if found_flg
    end while(count > 0)
  end
end

if !project_found_flg then
  puts 'project not found'
  exit!
end

if !found_flg then
  puts 'merge request not found'
  exit!
end

target_description.gsub!(/(\r\n|\r|\n)/, "\n")

puts target_description
````

↑のスクリプトを~/get_gitlab.rbとして以下のようなシェルスクリプトを使うとコミットメッセージにコメントを取り込めます。

````sh
#!/bin/sh

if [ $# -lt 2 ]; then
  echo "usage ${0} project_name merge_request_number"
  exit 1
fi

MY_COMMENT="`ruby ~/get_gitlab.rb ${1} ${2}`"

cat <<MYEOT
git commit -F- <<EOT
${MY_COMMENT}
EOT
MYEOT
````
CakePHP 2.x + MySQLでSQLのWHERE句にCOLLATEを指定する

# CakePHP 2.x + MySQLでSQLのWHERE句にCOLLATEを指定する

## 動機

照合順序がutf8_binのカラムに対して、find時に一時的に照合順序をutf8_unicode_ciなどに変更したい！

## 実装

正攻法ではできなかったのでデータソースをいじりました。

- https://github.com/sadapon2008/mysql_collate

## 注意点

- かなり力技なので適用範囲は極力絞ることをオススメします。
Windows上でNode.jsからSQLite3を使う方法

WindowsでNode.js+SQLite3を使おうとして、インストールでつまずいたのでインストール方法をメモ。

# 簡単にインストールしたいのに...

Mac OS XやLinuxでは、以下のようにコマンド一発でインストールできるのに、Windows10でやったらエラーになりました。(node.jsがv4.0.0のとき)

```
npm install -g sqlite3
```

実行して出たエラーを見ると、どうやら、Pythonが必要な様子です。

# Pythonのインストール

Pythonの公式サイト( https://www.python.org/downloads/ )よりPython2.7.xのインストーラーをダウンロードしてインストールします。そして、Python27にパスを通します。標準パスにインストールした場合は、管理者権限でコマンドプロンプトを起動して以下を実行します。

```
setx /m path "%path%;c:\Python27"
```

パスを通したら、Pythonが使えるので、これでOKです。


# Visual Studioをインストール

これでOKだと思ったら、以下のようなエラーが出ます。

```
C:\Users\kujira\node_modules\sqlite3\build\binding.sln : error MSB3411: Visual
C++ コンポーネント "VCBuild.exe" を読み込めませんでした。コンポーネントがインス
トールされていない場合は、次のいずれかを行ってください。1)
 Microsoft Windows SDK for Windows Server 2008 と .NET Framework 3.5 をインスト
ールする。2
) Microsoft Visual Studio 2008 をインストールする。
```

そのため、以下より、Visual Studioあるいは、SDKをインストールする必要があります。

- https://www.visualstudio.com/products/free-developer-offers-vs.aspx 


# 改めて npm を実行

無償のVisual Studioをインストールしている環境では、これでうまく行きました。

```
npm install -g sqlite3
```
express (node.js) での定石

忘れないように express (node.js) での定石を集めていこうと思います。

### ヘッダ処理
app.js の先頭付近

```
app.use(function (req, res, next) {
  res.removeHeader('X-Powered-By');
  res.removeHeader('ETag');
  res.header('Cache-Control', ['private', 'no-store', 'no-cache', 'must-revalidate', 'proxy-revalidate'].join(','));
  res.header('no-cache', 'Set-Cookie');

  // リモートIPアドレス(お好みで)
  req.remoteAddress = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  next();
});
```

### View Engine 関連

```
app.set('view engine', 'jade');
app.engine('html', require('ejs').renderFile); // .htmlはejsを利用

// react(お好みで)
app.engine('jsx', require('express-react-views').createEngine());
require('node-jsx').install({extension: '.jsx'});
```
Cake2でURL直打ちでのアクセスを拒否する

#Cake2でURL直打ちでのアクセスを拒否する


###画面上で非表示にしているが、データがあるためURL直打ちだとアクセスできてしまうことがあるので、それを防ぐ方法。

###Controller

```

public function detail($id = null) {
       $conditions = array('Model.delete_flag' => 0);
 
       if (!$this->Model->exists($id, $conditions)) {
          $this->redirect(array('controller' => 'home', 'action' => 'index'));
       }
}

```

###Model

```
	public function exists($id = null, $additionalConditions = null) {
		if ($id === null) {
			$id = $this->getID();
		}
		if ($id === false) {
			return false;
		}
		$conditions = array($this->alias . '.' . $this->primaryKey => $id);
		if ($this->schema('delete_flag') != null) {
			$conditions[$this->alias . '.delete_flag'] = 0;
		}
		if ($additionalConditions !== null && is_array($additionalConditions)) {
			$conditions = array_merge($conditions, $additionalConditions);
		}
		return (bool) $this->find('count', array('conditions' => $conditions, 'recursive' => -1, 'callbacks' => false));
	}
```
複数行またがるテキストアンダーライン


文中の一部、強調の為にアンダーラインを引きたい。

`text-decoration` では 1px のアンダーラインしか引けない。

アンダーライン1pxでもいいですか？ → 3px じゃないとダメ

アンダーラインじゃなくて背景色でマーカーで塗った感じでもいいですか？ → 却下

困った。

仕方無いから画像作るか・・・ → イケてない

で、思いつきました。

```html:html
<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<em>ここ強調したい</em>テキストテキストテキストテキストテキスト<em>ここ強調したい</em>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<em>ここ強調したい</em>テキストテキストテキストテキスト</p>
```

```scss:scss
em {
	position: relative;
	display: inline-block;

	&:after {
		content: '';
		position: absolute;
		left: 0;
		bottom: 0;
		z-index: -1;
		width: 100%;
		border-bottom: 3px solid #ffef00;
	}
}

```

これでもいい感じなんだけど、親要素の幅と文書量の兼ね合いで、右側に無駄な余白が発生しまくる場合がある。 → イケてない

で、結果こんな感じで解決しました。

```scss:scss
em {
	@include box-shadow(inset -3px -6px 0 -3px #ffff00);
}

```

CSS3 万歳！！
プロジェクトファイル名取得

# プロジェクトファイル名（exeファイル名）取得方法

・Application.ExecutablePath プロパティを使う
・Path.GetFileNameメソッドを使う

手順）
1.System.Windows.Formsを参照追加して、usingで名前空間を指定

2.System.IO.Path.GetFileNameで取得したプロジェクトファイルからファイル名を取得する


サンプルコード

```c#
var path = System.Windows.Forms.Application.ExecutablePath;
var projectName = System.IO.Path.GetFileName(path);
```
Power Assert .NETをVB.NETで使ってみたかった

power-assertの.NET版は無いのか！と思ってググってみたところ
なんと見つかったので試しに使ってみた。
https://powerassert.codeplex.com/

#感想
どうにか使えなくもないけど、結果表示が微妙・・・

#やったこと
１．新しいプロジェクトを作り、テストプロジェクトを追加する。

２．PowerAssertのDLLをダウンロードして、テストプロジェクトに追加

３．PowerAssertのページで紹介されているC#のコードをVB.NETに翻訳
https://powerassert.codeplex.com/

```lang:VB.Net
Imports System.Text
Imports PowerAssert

<TestClass()>
Public Class UnitTest1

    <TestMethod()>
    Public Sub RunComplexExpression()
        Dim x = 11
        Dim y = 6

        Dim d = New DateTime(2010, 3, 1)

        PAssert.IsTrue(Function() x + 5 = d.Month * y)
    End Sub

End Class
```

４．テスト実行！！

#出力結果
テスト失敗すると例外が投げられて、エラーメッセージにPowerAssertの出力結果が格納されている。↓こんな感じ。
![image](https://qiita-image-store.s3.amazonaws.com/0/48472/8e2beb21-6e1a-e944-08cb-ef625501ef07.png)

ずれてる！！しかも横に長い！！！
ずれてるのはフォントの問題だとしても、
無名関数外の変数名が分かりにくくて、何かキモい。
C#向けのライブラリだからしょうがないんだろうけど、使っていくかは微妙です。
FreeBSD に GitBucket をインストール

## <i class="fa fa-paw fa-fw"></i>FreeBSD に GitBucket をインストール

無線 LAN AP を構築したら，転がってた USB 無線 LAN のアダプターを使ったせいか設定が悪かったのか，半日ぐらいすると発熱でハングアップしていたので，こましなアダプターが見つかるまで保留することにする．

気を取り直して，ファイルサーバーを構築しようと思ったのだが，Samba も 4.3.0 と 4.2.4 リリース直前だったのでリリース後入れることにする．最近は，ソースからインストールが億劫な歳に差し掛かってきたので，Ports がでるまで待つことにする．（9/8 にリリースされました．）

そこで，GitHub のクローンを構築をしようと思い，GitBucket をインストールすることにした．Java ベースは個人的に重いイメージがあるので，GitLab の方が好みではあるけど，アップデートの手間を考えて GitBucket を選択する．

## <i class="fa fa-leaf fa-fw"></i>Tomcat 8
この辺は，サクッと Package でインストールする．
（root で作業）

```
# pkg install tomcat8
# rehash
```

インストールが終われば，`service tomcat8 onestart` で Tomcat を起動する．
`http://ip-address:8080` で動作しているか確認する．(pf でポート 8080 を止めている場合，アクセスできないので 8080 を許可する)

`service tomcat8 onestop` で Tomcat を停止する．

起動時にサービスが起動してほしいので，`/etc/rc.conf`に下記内容を追加する．

```rc.conf
tomcat8_enable="YES"
```

## <i class="fa fa-leaf fa-fw"></i>GitBucket
[ここ](https://github.com/takezoe/gitbucket/releases)から，「gitbucket.war」をダウンロードする．

```
# cd /usr/local/apache-tomcat-8.0/webapps
# curl -O https://github.com/takezoe/gitbucket/releases/download/3.6/gitbucket.war
```

Proxy 環境では，`curl -x http://user:password@proxy:port -O url` としてダウンロードする．

FreeBSD の tomcat のユーザは，`www` で，ホームディレクトリが `/nonexistent` で存在しないので，GitBucket のデータを保存するディレクトリを指定する必要がある．（参考）[Qiita](http://qiita.com/kkimura/items/f51303d3beba02e3e781)

` /usr/local/apache-tomcat-8.0/bin/` に `setenv.sh` を作成して，`GITBUCKET_HOME` を指定する．

```
# mkdir /home/gitbucket
# chown www:www /home/gitbucket
# vi /usr/local/apache-tomcat-8.0/bin/setenv.sh
# chmod +x /usr/local/apache-tomcat-8.0/bin/setenv.sh
```

```setenv.sh
#!/bin/sh

export GITBUCKET_HOME=/home/gitbucket
```

Tomcat を起動すると，`webapp` に置いた `gitbucket.war` が配備されるで，Tomcat を起動して動作を確認する．

```
service tomcat8 start
```

データを初期化したければ，`/home/gitbucket` を削除すればよい．

SSH で接続するのに `System Settings` の `SSH access` を有効にするときに，`SSH Port` を指定するが，GitBucket が独自に sshd サーバを起動するので，sshd サーバのポートと別のポートを指定する．(pf でポートを制限している場合は，このポートもアクセス許可する)

## <i class="fa fa-leaf fa-fw"></i>トラブル
ある環境において ssh からの `git clone` がうまくいかない．
`Unable to negotiate with xx.xx.xx.xx: no matching host key type found.Their offer: ssh-dss　fatal:` のようなメッセージが出て，ssh で接続出来ないので，調べてみるとOpenSSH の 7.0 から DSA(ssh-dss) の脆弱性により無効にされたことが原因のようです．

将来的には GitBucket もRSAに対応してくれると思うのですが，一時的な対応としてクライアント側で対応します．

`~/.ssh/config` で特定ホストに対して，ssh-dss の認証を有効にする．

```config
Host GitBucketのホスト名(or IP)
    HostKeyAlgorithms ssh-dss
```

後は，`Apache` か `Nginx` と連携させてSSLの対応もしたいのだけど，どちらのサーバを利用するか決めていないので決まるまで持ち越しです．

## <i class="fa fa-leaf fa-fw"></i>アップデート
(2016/03/04)久しぶりにアップデートしたらトラブったのでメモを更新します．
Gitbucket 3.12 が出ていたので，gitbuket.war を置き換えて更新してみたら，404 が表示されました><;
Gitbuketのリリース情報を確認すると，3.11 から Java 8 が要求されてましたので、さっそく更新します．

```
# service tomcat8 stop
# pkg set -o java/openjdk7:java/openjdk8
# pkg delete openjdk
# pkg install -Rf www/tomcat8
# service tomcat8 start
```
でアクセスすることができたが，上記トラブルで書いた RSA の対応がされたようで，`~/.ssh/config` の設定を削除します．一応，`~/.ssh/known_hosts` の該当するサーバの行も削除しました．
個人的grepのエイリアス

カレントディレクトリ以下の再帰検索をよく使うのだけど、打つのが面倒くさいのでエイリアス登録。
ackやagが入ってない環境のことも考えて・・・一応こっちも登録しておく。

bashなので、エイリアスというか関数で作る。

fgrepなのは、意外と正規表現を使わないから。それよりもレスポンスが速い方がいい。正規表現を使いたくなったら他のコマンドを使う。

```bash
# ~/.bashrcなどに追記。
# C/C++用
function grepc() {
  LANG=C fgrep --color -Inr \
    --exclude-dir='.git' \
    --exclude-dir='.svn' \
    --include='*.h' \
    --include='*.hpp' \
    --include='*.m' \
    --include='*.c' \
    --include='*.cc' \
    --include='*.cpp' \
    "$1" .
}

# header only
function greph() {
  LANG=C fgrep --color -Inr \
    --exclude-dir='.git' \
    --exclude-dir='.svn' \
    --include='*.h' \
    --include='*.hpp' \
    "$1" .
}

# Webっぽい言語用
function grepw() {
    LANG=C fgrep --color -Inr \
      --exclude-dir='.git' \
      --exclude-dir='.svn' \
      --exclude-dir='node_modules' \
      --exclude-dir='vendor' \
      --exclude='*.min.js' \
      --exclude='*.min.css' \
      --include='*.js' \
      --include='*.ejs' \
      --include='*.css' \
      --include='*.scss' \
      --include='*.html' \
      --include='*.php' \
      --include='*.sql' \
      --include='*.rb' \
      --include='*.pl' \
      --include='*.py' \
      "$1" .
}
```
ストックしたら負けのVB6アプリの .NET 移行メモ

# VB6 → VB.Net のコンバーターは VisualStudio 2010 以降、搭載されなくなった

一旦、次の Visual Studio のいずれかで、古いバージョンの VB.Net にコンバートする必要あり

- Visual Studio .NET (2002)
- Visual Studio .NET 2003
- Visual Studio 2005
- Visual Studio 2008

# Visual Studio 2008 （例）で VB6 ソースをコンバートする

コマンドプロンプトより：

```
$ "c:\Program Files\Microsoft Visual Studio 9.0\VB\VBUpgrade\VBUpgrade.Exe" (プロジェクト).vbp
Microsoft(R) Visual Basic アップグレード ツール バージョン 9.0.20913.0
Copyright(C) Microsoft Corporation.  All rights reserved.
Portions Copyright (C) Artinsoft Corporation

アップグレードしています。....................
例外が発生しました: 参照された コンポーネント を読み込めませんでした:
　　　（中略）
参照されたすべてのコンポーネントを含めて Visual Basic 6.0 をインストールすることを推奨します。アップグレードの前に、アプリケーションがコンパイルおよび実行されることを確認してください。
```

# コンバートエラー解消

* 推奨されたので Visual Studio 6.0 も入れる
* コンポーネントを含む製品をインストールする
* どうしても該当製品の入手が難しい場合、Visual Studio 6.0 で `(プロジェクト).vbp` を開いて、「プロジェクト」→「参照設定」から該当ライブラリファイルを消す

上記を行うことで、VBUpgrade.Exe でのコンバートは出来るようになり、サブディレクトリ OutDir 以下にコンバート結果が生成される

# 最新の Visual Studio へ更にコンバートする

```
$ start OutDir\(プロジェクト).vbproj
```

で開くと、変換ウィザードが起動する。最終的に `(プロジェクト).sln` が出来れば Ok。

# ひたすら文法エラーを解消する

俺たちの戦いはこれからだ！Never End！
（そういって、数百件の文法エラーに立ち向かってゆく主人公）

# (必要に応じて)VB6 のインストールされていない環境に移行する

現状だと、VB6関連の DLL が必要となってしまう。そのため、なるべく早く、VB6が無い環境に移行して、VB6 の DLL に依存していたコードを修正する。
（自分の経験だと、表関連のコントロールを、DataGridView まわりに改めなければいけなくなることが多かった）

# その他（トラブルシューティング）

## フォームのデザイナーが開けないケース

デザイナーで開こうとすると、「**値を Null にすることはできません。パラメーター名: objectType**」などというエラーが出て、「無視して続行する」を行わない限り、フォームデザイナーが開けない場合がある。

原因は全く不明だが、コードの方の `Handles` 句を一旦 `' Handles...` 等とコメントアウトしてからだとデザイナーで開ける。一度、デザイナーで正常に開けると、コメントアウトを元に戻しても、普通に開くことが出来た。どういう理由で直るのか不明

# (2019.10.04) 追記 ＜推奨作業＞

コンバート作業自体は以上で Ok だが、今後メンテナンスする上では以下を実施しておくことを推奨する

* インデントをタブだけにするか、スペースするだけかを統一する
* 'UPGRADE_WARNING の全削除

これを後まわりにすると、`svn blame` `git blame` などで「その行がいつ修正されたかのトレースする」が面倒になる。全ソースが修正される最初のうちに、全ソースに修正が入る以上の対応を行っていた方がよい

# 参考文献

- [Microsoft Visual Studio - Wikipedia](https://ja.wikipedia.org/wiki/Microsoft_Visual_Studio)
- [VB 6 を VS 2012に変換するには？ - Visual Basic | 教えて！goo](http://oshiete.goo.ne.jp/qa/7794035.html)
Javascriptで2x2のクロス表の独立性検定（ABテスト）

A/Bテストの評価を簡単にブラウザ上でできるようにしたい。ということで実装してみた。
そういえばGoogleスプレッドシートでもカイ2乗検定はできないのね。
これを使えばスプレッドシートから値を持ってきて簡単に検定できるかも。

## A/Bテストの技術的整理

A/Bテスト（2群の比率の差の検定）をするとき、比率を扱うので2項分布を使う方法もあるが、クロス表で扱うこともできる。

たとえば

|creative|imp  |click|
|:------:|:---:|:---:|
| A      |$x_0$|$x_1$|
| B      |$x_2$|$x_3$|

において

    クリエイティブAとBとでCTRが変わらない

すなわち

    クリエイティブの違い（行）とクリックのしやすさ（列）は独立

かどうかを検定したい。一般に検定で用いられるクロス表は

|グループ|○○する|○○しない|
|:-----:|:----:|:-----:|
| A     |      |       |
| B     |      |       |

という形式になるので、
クリックのしやすさは「クリックする or クリックしない」だから

|creative|クリックする|クリックしない|imp（周辺度数）|
|:------:|:---------:|:-----------:|:------------:|
| A      | $x_0-x_1$ |    $x_1$    | $x_0$        |
| B      | $x_2-x_3$ |    $x_3$    | $x_2$        |

というクロス表の独立性の検定をすることになる。

## 実装

```js
/**
 * Returns p-value of x.
 * @param {Array} x [[nTrial1, nOccurrence1], [nTrial2, nOccurrence2]]
 * @returns {Number} p-value
 */
function getChisq(x){

	if(x !== undefined){

		// Observations
		var o = [
			x[0][0] - x[0][1],
			x[0][1],
			x[1][0] - x[1][1],
			x[1][1],
		];

		var s = o[0]+o[1]+o[2]+o[3];

		// Expectations
		var e = [
			(o[0]+o[1]) * (o[0]+o[2]) / s,
			(o[0]+o[1]) * (o[1]+o[3]) / s,
			(o[2]+o[3]) * (o[0]+o[2]) / s,
			(o[2]+o[3]) * (o[1]+o[3]) / s,
		];

		var chisq = 0;
		for (i=0; i<=3; i++){
			chisq += (o[i] - e[i]) * (o[i] - e[i]) / e[i];
		}

	return chisq;

	}
}

// Cumulative distribution function of Normal distribution
// See http://qiita.com/gigamori/items/e17e6f9faffb78822c56
function cdf(x) {

    // constants
    var p  =  0.2316419;
    var b1 =  0.31938153;
    var b2 = -0.356563782;
    var b3 =  1.781477937;
    var b4 = -1.821255978;
    var b5 =  1.330274429;

    var t = 1 / (1 + p * Math.abs(x));
    var Z = Math.exp(-x * x / 2) / Math.sqrt(2 * Math.PI);
    var y = 1 - Z * ((((b5 * t + b4) * t + b3) * t + b2) * t + b1) * t;

    return (x > 0) ? y : 1 - y;
}

// Example
cdf(Math.sqrt(getChisq([[10000,100],[5000,45]])));
```

`cdf()`は正規分布の累積分布関数。自由度1のカイ2乗分布は平方根が片側標準正規分布になるので`cdf(Math.sqrt(...)`としている。
http://qiita.com/gigamori/items/e17e6f9faffb78822c56


## GoogleスプレッドシートでABテスト

2x2のセルを指定して実行すればOK！

```js
var values = SpreadsheetApp.getActiveSheet().getRange('A1:B2').getValues();
var p = cdf(Math.sqrt(getChisq(values)));
Logger.log(p);
```
Android Studio に Fabric プラグインをインストールする


まずはじめに、Fabricのプラグインをダウンロードします。
https://fabric.io/downloads

ここでいきなり注意なのが、
###Safari以外のブラウザでダウンロードすること。
Safariでダウンロードすると、zipファイルが勝手に解凍されてしまってその後のインストールがうまく行きません。

```
Plugin 'com.crashlytics.tools.androidstudio' failed to initialize and will be disabled.  Please restart Android Studio.
```

##以上です。

このあとはここの指示に従ってやっていただければ大丈夫です。
http://dev.classmethod.jp/smartphone/android/android-fabric-crashlytics-beta-distribution/
Spark1.5.0 - レーベンシュタイン距離を計測する

Spark 1.5.0 で追加された関数の中にレーベンシュタイン距離があったので簡単に確認してみました
半備忘です

## レーベンシュタイン距離とは？
簡単に言うと「単語の類似度」を図るロジックです
単語Aを単語Bにするまで何回操作が必要かという回数を表します
似た単語なんかを探すときによく使うロジックですね

https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%BC%E3%83%99%E3%83%B3%E3%82%B7%E3%83%A5%E3%82%BF%E3%82%A4%E3%83%B3%E8%B7%9D%E9%9B%A2

## Sparkソースコード
詳しくは↓のPRを
SparkSQL関数で使うのが主になるのかなあと
https://issues.apache.org/jira/browse/SPARK-8270

## Spark-shell上での確認
marioとmaro, sevrとserviceそれぞれの単語間距離を測りました
いい感じです

```scala
scala> Seq(("mario", "maro"), ("sevr", "service")).toDF("l", "r").selectExpr("levenshtein(l, r)").show()

+-----------------+
|'levenshtein(l,r)|
+-----------------+
|                1|
|                4|
+-----------------+
```
Gitbookインストールメモ


MacでのローカルへのGitbookのインストールメモ。
Homebrewインストール済みが前提。

# 各種インストール手順

## node.jsのインストール

```
brew install node
```

## npmのインストール
```
brew install npm
```

## gitbookのインストール
```
npm install gitbook -g
```

## calibreのインストール

### ダウンロード
ダウンロードリンク: [calibre](http://calibre-ebook.com/download)

### パスを通す

シンボリックリンクの場合

```
ln -s /Applications/calibre.app/Contents/console.app/Contents/MacOS/ebook-convert ${どっかのbinとか}
```

普通にパスを通してもいいっぽい
プラグインのインストールに失敗する　"Could not create directory."

###現象
ダッシュボードのプラグイン検索から入れたいものを選んで、DLとか解凍まで進んだのに、"Could not create directory."のエラーメッセージで止まっちゃう。
環境：WordPress3.8.5*PHP5.3
※古いバージョンのWPなのは本番で動いてる環境に合わせてるため。
![WS000009.png](https://qiita-image-store.s3.amazonaws.com/0/59364/6bc38131-0141-307e-bbf5-104f6103c6b6.png)

###調査
最初エラーメッセージでググったけど、対処法を試してみても上手く行かず。
[WordPress Pluginのインストールが失敗する](http://blog.pc-logon.com/?p=2120)
[WordPress: Could not create directory – Plugin Install Failed](http://stuff24.de/blog/wordpress-could-not-create-directory-plugin-install-failed/)

「そもそもsafe_modeってなんだろう？」とアプローチを変える。
[セーフモードによる制限と対処方法 - WordPress Codex 日本語版:](https://wpdocs.osdn.jp/%E3%82%BB%E3%83%BC%E3%83%95%E3%83%A2%E3%83%BC%E3%83%89%E3%81%AB%E3%82%88%E3%82%8B%E5%88%B6%E9%99%90%E3%81%A8%E5%AF%BE%E5%87%A6%E6%96%B9%E6%B3%95)
>PHP がセーフモードで動作するサーバの場合、WordPress の一部の機能に制限が生じます。このページでは、セーフモードにより問題が生じる機能とその対処方法をまとめています。

phpinfo()で見に行ったら、offだったから、これではないっぽい。
よくよく[プラグイン新規インストール](https://wpdocs.osdn.jp/%E3%82%BB%E3%83%BC%E3%83%95%E3%83%A2%E3%83%BC%E3%83%89%E3%81%AB%E3%82%88%E3%82%8B%E5%88%B6%E9%99%90%E3%81%A8%E5%AF%BE%E5%87%A6%E6%96%B9%E6%B3%95#.E3.83.97.E3.83.A9.E3.82.B0.E3.82.A4.E3.83.B3.E6.96.B0.E8.A6.8F.E3.82.A4.E3.83.B3.E3.82.B9.E3.83.88.E3.83.BC.E3.83.AB)の項を読んでみると、**方法 1： 事前に作業ディレクトリを作成しておく**と**方法 2： PHP を CGI モードで動かす**の二択。
モードを変えるのは多分権限ないしよく分かってなくてリスキーなので、FTPソフトからディレクトリを作って、プラグインをDL・解凍してアップロード。
![WS000010.png](https://qiita-image-store.s3.amazonaws.com/0/59364/cad8d071-0816-334f-c0e5-86486f39ce9e.png)
選べるようにﾅﾘﾏｼﾀﾜｰ!

![WS000011.png](https://qiita-image-store.s3.amazonaws.com/0/59364/33bd8c1f-baae-be53-a478-fa6b54df372c.png)
アクティベートもﾃﾞｷﾀ!

###おまけ
そもそも動作モードがなんなのかもわからなかったのでググった：
調べ方→[phpの動作モードを調べる(CGI版?モジュール版?)](http://server-domain.info/report/check-php-cgi-module.html)
違い→[あなたのサイトの PHPは，CGI方式ですか？ Module方式ですか？](http://www.fumi.org/neta/201205sv.html)

###派生課題とか
あとでよむ：
[セーフモードの束縛](http://zone.maple4ever.net/blog/archives/657/)


権限がないからディレクトリが作れないっていういのがダッシュボード上で分かっていたら、ここまで遠回りしなかった気もする…
エラーのログをどこかに吐いておく設定を先にしておけばよかったのかな？？
Ubuntu 12.04にJRuby9.0.0.0をインストール

# Java-8-oracleをインストール

java8をインストール

```
$ sudo apt-get install software-properties-common python-software-properties
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer
```

バージョンの一覧を見る

``` 
$ sudo update-java-alternatives -l
java-1.6.0-openjdk-amd64 1061 /usr/lib/jvm/java-1.6.0-openjdk-amd64
java-1.7.0-openjdk-amd64 1051 /usr/lib/jvm/java-1.7.0-openjdk-amd64
java-8-oracle 1062 /usr/lib/jvm/java-8-oracle
``` 
 
バージョンの切り替え
 
```
$ sudo update-java-alternatives -s java-8-oracle
```

## インストール失敗(JAVA_HOMEの影響)

jrubyをインストールしようとすると、以下のエラーが発生。

```bash
$ rbenv install jruby-9.0.0.0
Downloading jruby-bin-9.0.0.0.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/655665db3a1dc0462cba99d45532ab57d8416b5f168d8a0081bde9b7a93a394e
Installing jruby-9.0.0.0...

BUILD FAILED (Ubuntu 12.04 using ruby-build 20150818)

Inspect or clean up the working tree at /var/tmp/ruby-build.20150911110027.21049
Results logged to /var/tmp/ruby-build.20150911110027.21049.log

Last 10 log lines:
/var/tmp/ruby-build.20150911110027.21049/jruby-9.0.0.0 /var/tmp/ruby-build.20150911110027.21049 /var/www/xxx
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/jruby/Main : Unsupported major.minor version 51.0
	at java.lang.ClassLoader.findBootstrapClass(Native Method)
	at java.lang.ClassLoader.findBootstrapClass0(ClassLoader.java:909)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:318)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:316)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
Could not find the main class: org.jruby.Main. Program will exit.
```

原因は、環境変数`JAVA_HOME`にjava-6が指定されていたことだったので、JAVA_HOMEを削除する

```bash
$ echo $JAVA_HOME
/usr/lib/jvm/java-6-openjdk-amd64
unset JAVA_HOME
$ echo $JAVA_HOME
```

# 再度インストール(成功)

```bash
$ rbenv install jruby-9.0.0.0
Downloading jruby-bin-9.0.0.0.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/655665db3a1dc0462cba99d45532ab57d8416b5f168d8a0081bde9b7a93a394e
Installing jruby-9.0.0.0...
Installed jruby-9.0.0.0 to /home/xxx/.rbenv/versions/jruby-9.0.0.0

```
SQL Server Express Editionの導入とインポート／エクスポート手順


まぁまぁつまったところがあったので、メモがてらに。


環境：AWSのWindows Server 2012（64bit）
導入バージョン：Microsoft SQL Server 2008 R2 RTM - Express


# 1．ダウンロード
依存ファイル：Microsoft .NET Framework 3.5 Service Pack 1
http://www.microsoft.com/ja-jp/download/details.aspx?id=22

DBサーバ：Microsoft SQL Server 2008 R2 RTM - Express
http://www.microsoft.com/ja-jp/download/details.aspx?id=3743

統合環境：Microsoft SQL Server 2008 R2 RTM - Management Studio Express
https://www.microsoft.com/ja-jp/download/details.aspx?id=22985

# 2．依存ファイルのインストール

1. ダウンロードから取得したdotnetfx35setupを開始し、画面に合わせて.NET Freamworkをインストール（Microsoft .NET Freamwork 3.5 SP1のみインストールで良い）

# 3．SQL Serverのインストール

1. ダウンロードから取得したSQLEXPR_x64_JPNをスタート
2. プログラム互換性アシスタントが出たら「ヘルプ情報を使用せずにプログラムを実行する」
3. 「新規インストールを実行するか、既存のインストールに機能を追加します。」
4. ライセンス同意
5. セットアップサポートファイルのインストール
6. 機能の選択「すべて選択」
7. 既定のインスタンス（そうしないとポートが変わるらしい）
8. サーバーの構成はデフォルトで次へ
9. 認証モードはリモートで接続するなら「混合モード」
10. saユーザのパスワード入力
11. インストール実施

# 4．SSMS（SQL Server Management Studio）のインストール

1. ダウンロードから取得したSQLManagementStudio_x64_JPNをスタート
2. プログラム互換性アシスタントが出たら「ヘルプ情報を使用せずにプログラムを実行する」
3. 「新規インストールを実行するか、既存のインストールに機能を追加します。」
4. セットアップサポートファイルのインストール
5. 新規インストールを実行するか共有機能を追加する（既存のSQL Server 2008 R2インスタンスに機能を追加するを選ぶと、インストーラーのバグにより、一旦戻って「新規～」を再度選択しても7．で管理ツール-基本が選択できない状態になってしまうので、そうなったら一度キャンセルしてもう一度SQLManagementStudio_x64_JPNをスタートするところからやり直してください)
6. ライセンス同意
7. 機能の選択で「管理ツール-基本」を選択
8. インストール実施

# 5．SSMSで接続確認

1. アプリ画面から「SQL Server Management Studio」を選択
2. 起動されたら、サーバー名に「localhost」、認証「Windows認証」を入力し、接続（リモートの場合は、サーバー名にIPアドレス、認証「SQL Server認証」でユーザ、パスワードを入力すればいいと思う）
3. オブジェクトエクスプローラーにlocalhost（もしくはIPアドレス）が表示されればOK！

# 6. データのエクスポート（バックアップ）

1．オブジェクトエクスプローラーから＋で展開
2．システムデータベースの中からエクスポートしたいデータベースで右クリック→タスク→バックアップ

# 7. データのインポート（復元）

1. オブジェクトエクスプローラーから＋で展開
2. データベース（もしくはシステムデータベース）を右クリック→データベースの復元
3. 復元用のソース→デバイスからをクリックし、bakファイルもしくはtrnファイルを選択
4. 復元先から、復元先データベースと復元する特定の時点を選択
5. 復元するバックアップセットの選択から復元するものにチェック
6. OK
【PHP】データベースに入れた画像をランダムで表示する方法

お目汚しすいません。ど素人の勉強ノートです。
今日は、データベースに入れた画像をランダムで表示する方法を勉強しました。PDOで呼び出してます。（データベースには、画像データと、画像typeが格納されています。）
細心の注意を払ってはおりますが、問題……あるかもしれません。
もし、ご指摘いただけるととても嬉しいです。よろしくお願いします。
## データベースに入れた画像をランダムで表示する
### データベース設定

```php:dbmanager.php
<?php
function getDb(){
$dsn = 'mysql:dbname=***; host=localhost; charset=utf8';
$usr = '****';
$psw = '****';
try {
$db = new PDO($dsn, $usr, $psw);
} catch (PDOException $e) {
 exit('データベース接続失敗。'.$e->getMessage());
}
return $db;
}
```

### サンプルコード

```php:sample.php
<?php
session_start();
require_once 'dbmanager.php';
try{
$pdo = getDb();
$stmt = $pdo->prepare("SELECT * FROM tables where image != '' and type != '' ORDER BY RAND() limit 1");
$stmt->execute();
} catch (PDOException $e) {
        echo $e->getMessage();
}
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION['image'] = $row['image'];
$_SESSION['type'] = $row['type'];
?>
<img src="UseImg.php">
```

（「!=''」は、空文字とnull値をはじく。）
### 呼び出す画像ファイル

```php:UseImg.php
session_start();
if (!isset($_SESSION['image'])) { die('abort'); }
$type = $_SESSION['type'];
header('content-type: $type');
echo $_SESSION['image'];
```

## 課題
自分の理解したことによると、sqlを外部から書き換えられる（フォームの値によって出力されるデータが変わるような）可能性がある場合、PDOの書き方は特に気をつけなきゃならない、と思っているので、今回のような場合は問題はなさそうなのですが……全然まだまだPDOを理解しきっていないので毎回、不安です。
sql文に「!=''」を入れても大丈夫なんだろうか、とか無意味に心配してしまう。

## 参考
・[PHP+MySQLで簡易画像アップローダ](http://qiita.com/mpyw/items/117ab6a88fd58d911c34)
画像保存に関して参考にさせていただきました。
・山田祥寛『独習PHP 第２版』（翔泳社, 2010年）
全体的にコチラの本を読みながら勉強しています。
privateやprotectedなフィールドの値をインスペクターから変更できるようにしたい

[SerializeField]
シリアライズフィールド属性を指定することで可能みたいです。

```cs:Rotator
public class Rotator : MonoBehaviour {

	[SerializeField] private float rotationSpeed;

	// Use this for initialization
	void Start () {
		//rotationSpeed = 10.0f;
	}

}
```

![スクリーンショット 2015-09-11 11.20.14.png](https://qiita-image-store.s3.amazonaws.com/0/76843/62d6229f-7c01-f9ba-3a78-9464d6015a7d.png)

以上
sedで指定行(特定の行)だけ置換する、指定行(特定の行)に文字列挿入する

3行目の「start」を「end」に置換したい時
`sed -e "3 s/start/end/g" hoge.txt`


3行目に「moge」を挿入したいとき
`sed -i -e "3i moge" hoge.txt`
[Swift] iOS でアプリを Background Mode で動かし、Background fetch をする

# まず

![Screen Shot 2015-09-11 at 10.33.23.png](https://qiita-image-store.s3.amazonaws.com/0/18705/834c1fed-df8f-7b4b-4498-2d5f735ed675.png)

# 次に

```swift:AppDelegate.swif
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
・
・
    /* Background fetch */
    UIApplication.sharedApplication().setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
    /* END: Background fetch */
    return true
}
```

↑の記述がないと動きません。

# 処理内容を書きます

````swift:AppDelegate.swift
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
        
        // ここに処理内容
        println("Background fetch foo")
       
        completionHandler(UIBackgroundFetchResult.NewData)
}
````

completionHandlerで、UIBackgroundFetchResult.NoData、UIBackgroundFetchResult.Failed、UIBackgroundFetchResult.NewDataのいずれかのステータスを返します。

# 確認

Debug > Simulate Background Fetch でシミュレーターを動かします。

![Screen Shot 2015-09-11 at 10.56.54.png](https://qiita-image-store.s3.amazonaws.com/0/18705/bd443a20-6488-0558-3e3a-e603922272d4.png)

動きました。

![Screen Shot 2015-09-11 at 11.06.45.png](https://qiita-image-store.s3.amazonaws.com/0/18705/764ecc00-009e-02a3-08d3-f8b7c21033d6.png)

シミュレーター上でアプリをバックグラウンド状態にしても動きます。
アノテーションとリフレクションで共通処理を実現する

最近初めてアノテーションを自作したので、
勉強がてら、アノテーションとリフレクションで共通処理を実現する方法を記載します。

例として、Webアプリケーションでよくあるバリデーションを共通的に行う方法を取り上げようと思います。

###①バリデーションを行いたいフィールドに対して付与するアノテーションクラスを定義します。

```lang:CommonValidation.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CommonValidation {
    
    String expression() default "";

}
```
@Retention(RetentionPolicy.RUNTIME)は、実行時にこのアノテーションが参照できるようにしています。
これを付けない(デフォルト(RetentionPolicy.CLASS))と、実行時に参照することが出来ません。
また、@Target(ElementType.FIELD)で、アノテーションを付けられる箇所を限定しています。
上記は付けなくても構いません。
ElementType.METHODにするとメソッド定義だけに該当アノテーションを付与できるように指定できます。

正規表現でフィールドを検証するので、String型のフィールドを定義します。
booleanやintegerのフィールドを定義して、
必須入力可否や桁数チェックを表現することも出来ます。

###②エンティティクラスのフィールドにアノテーションを付与します。

```lang:Customer.java
public class Customer {
    
    public String id;

    @CommonValidation(expression = ".{1,20}")
    public String name;

    @CommonValidation(expression = "\\d{1,12}")
    public String tell;
    
}
```
上記は簡素化した会員のエンティティです。
以下のバリデーションを定義します。

・nameフィールドは20桁以内であること。
・tellフィールドは1~12桁の数値型であること

###③バリデーション処理の定義とテスト実行

```lang:Executor.java
import java.lang.reflect.Field;

public class Executor {
    
    public static void main(String[] args) throws Throwable {
        Customer customer = new Customer();
        customer.name = "テスト";
        customer.tell = "1234567890123";
        
        boolean isValidResult = validate(customer);
        System.out.println(isValidResult);
    }

    public static boolean validate(Object obj) throws IllegalArgumentException, IllegalAccessException {
        Field[] fields = obj.getClass().getFields();
        boolean isCorrectData = true;
        for(Field f : fields) {
            if(f.isAnnotationPresent(CommonValidation.class)) {
                String expression = f.getAnnotation(CommonValidation.class).expression();
                if(expression.length() == 0) continue;
                String val = f.get(obj).toString();
                if(!val.matches(expression)) {
                    System.out.println(f.getName() + " value is " + val + ". not matches " + expression);
                    isCorrectData = false;
                }
            }
        }
        return isCorrectData;
    }
}
```

上記のvalidateメソッドの中で以下の処理を行っています。
１．エンティティクラスの全フィールドを取得
２．CommonValidationアノテーションが付与されているフィールドか確認
３．正規表現取得
４．正規表現とフィールドの値のマッチング処理

実行結果は以下の様になります。
>tell value is 1234567890123. not matches \d{1,12}
>false

また、メソッドにアノテーションを付与して、
共通的な処理の実行制御を行うことも出来て非常に強力なことも行えます。


※エンティティをpublicフィールドに出来ない場合は、validateの中で、Field.setAccessible(true)する必要があります。
16進数文字列 -> long


[todanano@localhost tmp]$ vi a.cpp
[todanano@localhost tmp]$ cat a.cpp

```c:

#include <stdio.h>
#include <stdlib.h>
#include <string>

int main( int argc, char **argv ) {

        std::string str = "FF";
        long num = strtol( str.c_str(), NULL, 16 );
        printf( "%ld\n", num );

        return( 0 );

}

```
[todanano@localhost tmp]$
[todanano@localhost tmp]$ g++ ./a.cpp
[todanano@localhost tmp]$ ./a.out
255
[todanano@localhost tmp]$
[todanano@localhost tmp]$

息抜きにちょろっと書いただけです。はい。
[Android]スクショや画面録画などにより画面を保存されたくないときの回避方法


## なぜ回避したいのか
ちょっと個人的に、Android 5.0から可能になった。Screen Record（`MediaProjection API`）について、ユーザーが許可した場合であってもコンテンツ的に録画してほしくないものがあったので録画されないようにする手段はないか調べていたら見つけたので共有します。

## やり方
[WindowManager.LayoutParams | Android Developers](http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SECURE)

WindowManagerのLayoutParamsに `FLAG_SECURE` というものがあり、Activityなどで以下のように設定すればOKです。

> Display flag: Indicates that the display has a secure video output and supports compositing secure surfaces.
> If this flag is set then the display device has a secure video output and is capable of showing secure surfaces. It may also be capable of showing protected buffers. 

[引用] : [Display | Android Developers](http://developer.android.com/reference/android/view/Display.html#FLAG_SECURE)


```
public class MainActivity extends Activity {

    @Override  
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
        setContentView(R.layout.main);
    }
}
```

## FLAG_SECUREで、どんなことができるのか
以下に使用した例を記載しておきます。これでイメージ湧くのではないでしょうか。

### ScreenShot（スクリーンショット）を無効化
Android 4.0 からスクリーンキャプチャ（以下スクショ）がとれるようになりました。上記の設定をするとその画面をスクショしようとするとエラーが発生してスクショがとれなくなります。

### ScreenRecord（スクリーンレコード）で画面を真っ黒にできる
Android 5.0 から画面をキャストすることができるようになりました。（要アプリ使用）上記の設定をするとスクリーンレコード中であっても該当画面の録画はできず真っ黒な画面が録画されるだけになります。

これにより、設定されている画面以外は録画できて、設定されている画面のときだけ画面が真っ黒になるのでユーザーとしても嬉しいですね。

### TaskManager（タスクマネージャー）上で画面を真っ黒にできる
みんな大好きタスクマネージャーですが、この画面でも上記の設定をすることで画面を黒くできます。

## どんなときに使うか
設定をすることで、良しなに画面を守ってくれるようになるので、権利問題やアプリの要件によっては容易に画面を共有できないようにしたい場合に有効です。

実際、そういう場合って困るレベルの要件だったりするので少しでも誰かの助けになればと思います。
便利ですね！ `FLAG_SECURE` !!

## ちなみに
Android 5.0 以降であれば、`MediaProjection API` を使うことで録画が可能です。アプリもいくつかあるみたいですね。

### 試すならこれが良さ気でした。
[Lollipop Screen Recorder - Google Play の Android アプリ](https://play.google.com/store/apps/details?id=com.rivulus.screenrecording&hl=ja)

### いつもお世話になっているTechBoosterさん
[Android 5.0 アプリからスクリーンショットを撮影する « Tech Booster](http://techbooster.org/android/application/17026/#more-17026)


## 謝辞
[Android 5.0 API | Android Developers](https://developer.android.com/intl/en/about/versions/android-5.0.html#UI)

> ### Screen capturing and sharing
> The API only allows capturing non-secure screen content, and not system audio. 

ドキュメントをみていて、この一文があったので回避できるのは間違いないようだったのですが、肝心の回避方法がこのドキュメントではわからず困っていました。そんなとき一緒に調べてくれて見つけてくれたのが、[@t-kashima](http://qiita.com/t-kashima)でした本当にありがとう。助かりました。
c++ builder > Cのソースをプロジェクトに追加して使う > ヘッダにextern "C" { } を追加

```txt:動作確認
C++ Builder XE4
```

## 問題

以下の状況とする。

- プロジェクトA (cプロジェクト)
- プロジェクトR (cppプロジェクト。C++ Builder XE4で開発)

以下のCソースがあり、A,Rプロジェクトで共有するとする。

```calc_bcc.c
#include "calc_bcc.h"

double calc_bcc(unsigned char *strPtr, int length)
{
	return 0.0;
}

double Test_calc_bcc(void)
{
	unsigned char testChars[] = "A,B,C,D,E,F,G";
	double res;

	res = calc_bcc(testChars, sizeof(testChars));

	return res;
}
```

XE4にて

- 上記のヘッダファイルを追加
- calc_bcc.cをプロジェクトに追加
- 使いたいcppファイルにて #inlcude "calc_bcc.h"してから Test_calc_bcc()などをコール

上記のようにすると以下のエラーがでる。

```
[ilink32 エラー] Error: 未解決の外部シンボル 'Test_calc_bcc()' が XXX.OBJから参照されています
```

マングル関係によるものと思われる。
http://qiita.com/7of9/items/475f06b4cf926f9508e4

## 対策

正しい方法かわからないが、ヘッダーにて以下のように`exter "C"`を追加すれば`プロジェクトR (cppプロジェクト)`でエラーが回避できた。

```calc_bcc.h
#ifndef calc_bccH
#define calc_bccH

#ifdef __cplusplus
extern "C" {
#endif

double calc_bcc(unsigned char *strPtr, int length);
double Test_calc_bcc();

#ifdef __cplusplus
}
#endif

#endif // calc_bccH
```

上記は`プロジェクトA (cプロジェクト)`でも問題なく使用できると思われる。
Pacemakerの基本(プロセス構成)

#Pacemaker1.1系(corosync+pacemaker)でのプロセスの関連と構成について

![pm1.png](https://qiita-image-store.s3.amazonaws.com/0/80018/7f3f3b27-9178-cd0c-18c9-e778adf8f572.png)

## corosync層
 - corosync : corosyncの本体(pacemakerとは別物)
 - cpg : Cluster Process Group Service - corosync配下にグループを作成し、グループ内でメッセージなどを配送するサービス(pacemakerもCPGサービスのクライアント)
 - quorum : Quorum Service - ノード数管理(QUORUM)サービス(pacemakerにQUORUM情報を伝搬)

## Pacemaker層
Pacemaker自体は、corosyncのCPGサービスのクライアントとして動作する。
クラスタ間のメッセージ送信は、CPGサービスを利用して行う。プロセス間の通信は、IPCを利用して行う。

 - pacemakerd : 各以下pacemakerプロセスを起動、停止、監視するメインコントロール
 - crmd : クラスタマネージャー(クラスタ構成の管理などを行う、pengineにて作成された状態遷移の実行(自ノードのlrmdへの依頼、他ノードのcrmdへの依頼）も行う)
 - cib : CIB情報(リソース構成情報やノード状態、リソース状態）の更新、管理プロセス
 - pengine：状態遷移を計算するプロセス
 - attrd：属性管理プロセス
 - lrmd：ローカルリソースマネージャープロセス(自ノードのリソースの起動、停止、モニター)
 - stonith：STONITHプロセス
HomebrewでGo 1.5にアップデート後でエラーが発生

# HomebrewでGo 1.5にアップデート
Macのパッケージ管理には、Homebewを使っている。
普段開発で使っているGoのバージョンを1.5(正確には既に1.5.1だが)に上げる必要があり、いつもどおり`$ brew upgrade go`したのだが、その直後から以下のエラーが発生するようになった。

```
$ go test -v
"package runtime: C source files not allowed when not using cgo or SWIG: atomic_amd64x.c defs.c float.c heapdump.c lfstack.c malloc.c mcache.c mcentral.c mem_darwin.c mfixalloc.c mgc0.c mheap.c msize.c os_darwin.c panic.c parfor.c proc.c runtime.c signal.c signal_amd64x.c signal_unix.c stack.c string.c sys_x86.c"
```

# 原因の調査
Go 1.5ではC言語で書かれたコードが削除されたにもかかわらず、Go 1.4系の環境を参照してしまっているということかな? と推測。
まずGoが参照している`GOROOT`が何かを調べてみた。

```
$ go env GOROOT
/usr/local/Cellar/go/1.4.2/libexec`
```
案の定1.4系を参照している。
あれ、でも環境変数で`GOROOT`なんて設定してたっけ? と、.zshrcを見てみるも、そんな記述はない。

と、ここで気づく。
単にアップデート後、シェルを起動しなおしてなかっただけだと…

# 対策
単にシェルを再起動するだけ…

でもまた、同じ事を繰り返したくないので、

```
export GOROOT=$(brew --prefix go)/libexec
```
とでもしておこうか。

昔のGoは別として、今のGoはツールチェーン自体をビルドする際に標準インストールパス(Homebrewの場合は`/usr/local/Cellar/go/1.5.1/libexec`)が埋め込まれているので、そこにインストールしている限り`GOROOT`は設定しなくて良い。なので、`GOROOT`を明示的には設定してなかった。

でも、パスにバージョン番号が含まれてしまっているので、アップデート後にシェルを起動し直さないと参照パスが切り替わらない。
そこで、`brew --prefix go`で返ってくる `/usr/local/opt/go`(これは`/usr/local/Cellar/go/<バージョン>`へのシンボリックリンク)を使って明示的に指定することで、brewでアップデートすれば自動的に参照先も切り替わるようにしておく。

ついでに、`$ brew cleanup go`して、古い環境も削除しておいた。
Java プログラムでホスト名の名前解決ができなくなる原因。JVM の DNS キャッシュの仕組みと、キャッシュの有効期間を変更する方法

JVM は ホスト名を解決すると IP アドレスをキャッシュします。

# 発生する問題
あるサーバのホスト名が変化しなくても、IP アドレスが変わると、 Java のプログラムからそのサーバにアクセスできなくなることがあります。
具体的には、 AWS の ELB はホスト名が変わらずに IP アドレスだけ勝手に変化することがあるので、そのような場合に、名前解決に失敗します。
もちろんサーバ側の管理者が DNS の A レコードを変更したときにも発生するので、 AWS のみならず一般的に起き得ます。

# どのようにキャッシュしている？

## キャッシュを保持してある場所
InetAddress クラスがキャッシュを保持しています。
キャッシュが存在する限り、名前解決をしようとしても、キャッシュが参照されます。

## キャッシュの有効期間を決定する場所
InetAddressCachePolicy クラスがキャッシュの有効期間を決定しています。
キャッシュの有効期間には 2 種類あります。

1. 成功した名前解決の結果のキャッシュの有効期間
2. 失敗した名前解決の結果のキャッシュの有効期間

どちらもセキュリティプロパティで設定します。
セキュリティプロパティというのは、後述しますが、 $JAVA_HOME/lib/security/java.security というファイルに記述したりして設定できます。

セキュリティプロパティが読み込まれるのは、[InetAddressCachePolicy のソース](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/net/InetAddressCachePolicy.java)を見ると、 static 初期化子のなかです。
なので InetAddressCachePolicy クラスの static 初期化子が実行される前にセキュリティプロパティを指定すると、DNS キャッシュの有効期間を変更できます。
具体的には、ネットワークを使用するクラス全般を呼び出すと、InetAddressCachePolicy クラスもロードされて static 初期化子が実行されるので、ネットワークが関連してくるようなコードを実行するよりも先に、セキュリティプロパティを指定する必要があります。



# セキュリティプロパティを指定する方法
3 つの方法があります。

## $JAVA_HOME/lib/security/java.security に記述
1. 成功した名前解決の結果のキャッシュの有効期間
    * `networkaddress.cache.ttl=10`
2. 失敗した名前解決の結果のキャッシュの有効期間
    * `networkaddress.cache.negative.ttl=10`

単位は秒です。
値が -1 なら有効期間は無制限です。
値が 0 ならキャッシュは無効です。


## java.security.Security.setProperty() で指定
コードで指定する方法です。

1. 成功した名前解決の結果のキャッシュの有効期間
    * `Security.setProperty("networkaddress.cache.ttl", "0");`
2. 失敗した名前解決の結果のキャッシュの有効期間
    * `Security.setProperty("networkaddress.cache.negative.ttl", "0");`

前述した通り、 InetAddressCachePolicy クラスがロードされるよりも先に Security.setProperty() を実行する必要があります。
たとえば Log4j のロガーのインスタンスを作成すると、間接的に InetAddressCachePolicy クラスもロードしてしまうので、それよりも先に実行しなければいけません。
main メソッドがあるクラスの先頭に下のように書けば確実だとおもいます。

```java
static {
    Security.setProperty("networkaddress.cache.ttl", "0");
    Security.setProperty("networkaddress.cache.negative.ttl", "0");
}
```

$JAVA_HOME/lib/security/java.security に記述する場合と同じく、
単位は秒です。
値が -1 なら有効期間は無制限です。
値が 0 ならキャッシュは無効です。

## 起動オプションに指定
[仕様](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/net/properties.html) によれば将来的に使えなくなるかもしれない方法です。

```
java -Dsun.net.inetaddr.ttl=0 -Dsun.net.inetaddr.negative.ttl=0 （後略）
```

と指定します。
これも単位は秒で、 -1 は無制限、 0 はキャッシュ無効です

#　参考
* [InetAddress](https://docs.oracle.com/javase/jp/8/docs/api/java/net/InetAddress.html): InetAddress クラスの API 仕様。「InetAddressのキャッシュ」の章にキャッシュについての説明があります。
* [Apache TomcatからELBにアクセスする際に気をつけたい事 sun.net.inetaddr.ttl=-1](http://dev.classmethod.jp/cloud/apache-tomcat-elb-ttl-1/): Tomcat + ELB の組み合わせでこの問題が発生した事例を紹介されています。Tomcat を使用している場合の セキュリティプロパティの設定方法を紹介されています。
* [Java/Socket, InetAddressにおけるDNS名前解決の仕組みと networkaddress.cache.ttl](http://www.glamenv-septzen.net/view/1346): キャッシュの仕組みをコードのレベルで詳しく紹介されています。私がググった中では最も詳しいです。
[超簡単] spreadsheetを更新したら自動で更新日付を入れるGAS

# 今回のアウトプット

![image](https://qiita-image-store.s3.amazonaws.com/0/83135/2e0573a4-fb27-82d4-03bf-f2bc74ba357b.png)

簡単なGASでサクッと実装します。

# コード



```js:GoogleAppsScript
function insertLastUpdated() {
  var ss = SpreadsheetApp.getActiveSheet(); 
  var currentRow = ss.getActiveCell().getRow(); 
  var currentCell = ss.getActiveCell().getValue(); 
  var updateRange = ss.getRange('F' + currentRow) //更新日をいれる列をstringで指定。この場合はF列
  Logger.log(updateRange);
  //更新日の記入
  if(currentRow>1){ 
    if(currentCell) { 
      updateRange.setValue(new Date());
    }
  }
}
```

## トリガー

- トリガーを`値の変更`にしておくと、シート更新時に上記の機能が走ります。

![image](https://qiita-image-store.s3.amazonaws.com/0/83135/96ce3324-246f-20cf-1f5d-323bcc1991e2.png)

# コメント

- タスク管理系はspreadsheetでいろいろ自動化できそうですね。
- smarbyでは法人営業管理シートなどでこの機能が活躍中。