ページ

2013年12月31日火曜日

mac mavericksでpostgresをPHP PDO経由で使う方法

こんにちは、今回は今更ですが自分でMacのmountain lionからmavericksにアップデートしたときに
PHPとPDO経由でpostgresを利用できなくなったのでそちらに対するメモを記載.

ステップは以下のステップになります。
mac内にpostgresのサーバとなります。

1.Xcodeのインストール
2.postgres9.3のインストール
3.pgsqlとpdo_pgsqlのコンパイル
4.PHPのインストールとapacheの設定

このような構成になります。
早速実行


1.Xcodeのインストール


こちらのアプリはApp Storeから「Xcode」と検索を行っていただければダウンロードが行えます。
2G程度の要領が必要ですので注意です。


2.postgres9.3のインストール


まずはこちらからpostgres9.3系をDLします。
インストールは、よくあるもの名での割愛いたします。
通常のインストールなら、「/Library/PostgreSQL/9.3/」こちらに各種コマンド等がインストールされます。



3.pgsql・pdo_pgsqlのコンパイル

こちらからがメインになります。
まずはコンパイルを行うためにPHPのソースをダウンロードします.
以下一連の手順です。後ほど解説.

# brewが使えない場合は以下のコマンドでインストール
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"
brew install autoconf
# PHP4.x系だった場合は、パスを修正してください.
curl -O http://museum.php.net/php5/php-`php -v | grep 5. | cut -d " " -f 2`.tar.gz
tar -xzvf php-`php -v | grep 5. | cut -d " " -f 2`.tar.gz 
cd php-`php -v | grep 5. | cut -d " " -f 2`/ext/pgsql/
sudo phpize
# postgresのバージョンにより差があるので各自書き換えてください.
sudo ./configure --with-pgsql=/Library/PostgreSQL/9.3/
sudo make
sudo make install

cd ../pdo_pgsql/
sudo phpize
sudo ./configure --with-pdo-pgsql=/Library/PostgreSQL/9.3/
sudo make
sudo make install

mavericksでは初期では、pdo_pgsqlなどが組み込まれていないため
自分でソースからビルドする流れになっています。
上記が手順となります。

4.PHPのインストールとapacheの設定


インストールしたモジュールなどを読み取るため設定を変更します
sudo sh -c 'cat /etc/php.ini.default | sed -e "s/; extension_dir = \".\/\"/extension_dir=\/usr\/lib\/php\/extensions\/no-debug-non-zts-20100525/g" -e "s/;extension=php_pdo_pgsql.dll/extension=pdo_pgsql.so/g" -e "s/;extension=php_pgsql.dll/extension=pgsql.so/g" > /etc/php.ini'
sudo apachectl restart

こちらでインストールができたはずです。
extension_dirはもしかすると自分でカスタマイズする必要があるかもしれません。


最後に以下のコマンドで動作確認
php -i | grep pgsql
こちらでpgsqlが出てきたら動作できます。

2013年12月19日木曜日

Seleniumを使ってJavaScriptのエラーを検知しよう

Seleniumの回です。 受け入れテストなどで大活躍のSeleniumです。 いろいろ調べているとJavaScriptのエラーを検知できるので検知の仕組みと確認の仕方を検証します。 Javaで実装しエラーの確認方法まで実施します. まずHTMLに以下の文面を埋め込みましょう

OnErrorを使って検知
<script type="text/javascript">
window.javaScriptErrors = [];
window.onerror = function(errorMessage) {
  window.javaScriptErrors[window.javaScriptErrors.length] = errorMessage;
}
</script>
このような内容を用意実際以下のHTMLの用になる。

index_error.html

<html>
  <head>
    <title>Seleniumを使ってJavaScriptのエラーを検知しよう</title>
    <script type="text/javascript">
    window.javaScriptErrors = [];
    window.onerror = function(errorMessage) {
      window.javaScriptErrors[window.javaScriptErrors.length] = errorMessage;
    }
  </script>
  <script type="text/javascript">
    alert(a);
  </script>
  </head>
  <body>
    わざとエラーを出す.
  </body>
</html>

ではJava側の実装です。 面倒なのでMavenで行います.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.blogspot.tech.joke</groupId>
  <artifactId>selenium</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>selenium</name>
  <dependencies>
   <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.38.0</version>
    <systemPath></systemPath>
   </dependency>
  </dependencies>
</project>

こちらのプロジェクトを作成し以下のJavaを作成.

Main.java

package com.blogspot.tech.joke.selenium;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;


public class Main {
 public static void main(String[] args) {
      WebDriver driver = new FirefoxDriver();
      driver.get("http://localhost/index_error.html");
      JavascriptExecutor executor = (JavascriptExecutor) driver;
      System.out.println(executor.executeScript("return window.javaScriptErrors"));
      driver.quit();
 }
}
こちらのJavaを実行するとエラーが出力されます。
JavaScriptのエラーをクローニングし監視なども作れそうですね
もっと活用できそうなのでいろいろ検証中

2013年12月18日水曜日

日本の地ウイスキー通販についてpart.3

3回目になります

この回で終わりかも

玉泉堂酒造
ピークと呼ばれる一升瓶サイズのウイスキーです。
手頃な価格のためハイボールにどうぞw


相生ユニビオ
モルトウイスキーのレインボー三州です。
12年以上熟成のモルトを使用していて香りなど楽しめそうです。

宝酒造
キングウイスキー凛を出しているメーカーです。
4リットルのサイズもあるのでハイボールや友達との飲みのお供に



宮崎本店
こちらも一升瓶サイズ、由来が「戦後の混乱期に太陽と平和を願い「サンピース」と命名した、地ウイスキーです」とのこと


江井ヶ嶋酒造 個人的に好きなウイスキー「あかし」です。
癖が独特です。また種類が豊富です.

中国醸造 「戸河内ウイスキー」トンネルを利用し熟成させたウイスキーです。
スモーキーさが特徴

本坊酒造
マルスウイスキーとして売られ工場見学が良いところです。
駒ヶ岳が主ですが、おすすめがシングルカスクがあります。原酒をお楽しみください

このような感じで日本の地ウイスキー紹介でした
普段飲まないお酒でいっぱいしながら開発をする日々も良いものですw

2013年12月16日月曜日

postgres SQLチューニングpart2【WHERE句での検証】

postgresでSQLの記述で高速化を図ります。Part2
パラメータ調整で多々あるみたいですが効率の良いSQLについて検証してみます。
前回の検証の続きです。
検証内容は前回に似ています。
もっとより実務的なSQLのチューニングをはかります。

検証1


サイト毎の合計view数,conversion数を計算
SQL1 SELECT * FROM (SELECT site_id, site_name, SUM(view) AS view, SUM(conversion) AS conversion FROM site AS T1 INNER JOIN site_view AS T2 USING(site_id) WHERE date BETWEEN '2013/11/01' AND '2013/11/30' GROUP BY site_id, site_name ORDER BY site_id) AS S1 LIMIT 10 OFFSET 0;
SQL2 SELECT * FROM (SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view WHERE date BETWEEN '2013/11/01' AND '2013/11/30' GROUP BY site_id) AS T2 USING(site_id) ORDER BY site_id) AS S1 LIMIT 10 OFFSET 0;
上記のSQL1,SQL2を検証します.
前回とほぼ同一なのでシェルの実行等は省きます.


以下が検証結果です。
実行ファイル 1回目 2回目 3回目 4回目 5回目 6回目 7回目 8回目 9回目 10回目 最小 最大 平均
sql1.sql 417.611 376.637 420.722 350.816 316.651 322.067 335.734 307.371 385.674 370.905 307.371 420.722 360.418
sql2.sql 321.847 280.912 303.027 263.667 258.189 276.157 310.888 274.68 277.269 265.227 258.189 321.847 283.186

と検証結果はこのようになりました。
先ほどよりやや差は縮まりましたがやはりSQL2の方が早いです。


では、SQL1の記述は遅いのかを親のデータsiteにWHERE句をかけて試します
SQL1 SELECT * FROM (SELECT site_id, site_name, SUM(view) AS view, SUM(conversion) AS conversion FROM site AS T1 INNER JOIN site_view AS T2 USING(site_id) WHERE T1.site_name ~ '[0-5]$' GROUP BY site_id, site_name ORDER BY site_id) AS S1 LIMIT 10 OFFSET 0;
SQL2 SELECT * FROM (SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view GROUP BY site_id) AS T2 USING(site_id) WHERE T1.site_name ~ '[0-5]$' ORDER BY site_id) AS S1 LIMIT 10 OFFSET 0;

このようなSQLです、あえて遅くするために正規表現で記載

実行ファイル 1回目 2回目 3回目 4回目 5回目 6回目 7回目 8回目 9回目 10回目 最小 最大 平均
sql1.sql 1709.609 1729.138 1714.069 1862.493 1838.969 1752.116 1668.097 1701.067 1749.651 1714.535 1668.097 1862.493 1743.974
sql2.sql 1074.498 1056.323 1087.329 1060.741 1051.747 1133.521 1133.265 1143.876 1087.005 1065.277 1051.747 1143.876 1089.358

極端とまでは行かないが半分近くSQL2が早い良い書き方はこういったように
効率化できそうである。
と後もう1個検証したい・・・

HAVINGを使うかWHEREを使うかである
検証で早いであろうSQL2をベースに以下のないようで検証します
SQL1 SELECT * FROM (SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view GROUP BY site_id HAVING SUM(conversion) > 90000) AS T2 USING(site_id) WHERE T1.site_name ~ '[0-5]$' ORDER BY site_id) AS S1 LIMIT 10 OFFSET 0;
SQL2 SELECT * FROM (SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view GROUP BY site_id) AS T2 USING(site_id) WHERE T1.site_name ~ '[0-5]$' AND T2.conversion > 90000 ORDER BY site_id) AS S1 LIMIT 10 OFFSET 0;

HAVINGを利用したSQLがSQL1でWHERE句を利用したのがSQL2である
何方もどっちな気がしなくはないが検証

実行ファイル 1回目 2回目 3回目 4回目 5回目 6回目 7回目 8回目 9回目 10回目 最小 最大 平均
sql1.sql 1180.76 1383.684 1326.127 1376.931 1359.841 1411.559 1368.94 1324.281 1383.121 1211.007 1180.76 1411.559 1332.625
sql2.sql 1359.779 1306.331 1312.314 1350.094 1327.714 1377.518 1405.109 1362.456 1313.428 1146.364 1146.364 1405.109 1326.111
お〜結論何方もどっちであることが分かりました。


仮にPHPやJavaでWHERE句やHAVINGを動的生成するのならSQL2の方がやりやすそうな気がするのでSQL2に軍配あり? とま〜長々と検証していきました。


結論としては、GROUP BYを先に行いJOINしましょうに限る
今度は、月別レポートの作成で検証したいと思います。

postgres SQLチューニングpart1【基本文での検証】

postgresでSQLの記述で高速化を図ります。
パラメータ調整で多々あるみたいですが効率の良いSQLについて検証してみます。
前回のテストテーブルpostgresで連番のテストデータを作成のデータをもとにします。
検証する条件は以下です。
1.思いつくパターンを複数SQLを記載.
2.検証には10回のデータを用います.
3.\timingの値を検証結果とします.
4.limit offsetを利用回数毎に移動させます.
5.WHERE句の有無での変化を確認.
上記条件が主なないようになります。

site,site_viewこちらの2テーブルの検索です。
\timingと呼ばれるコマンドを利用することで簡単に実行時間を
計ることができるのでこちらを利用.

検証1


サイト毎の合計view数,conversion数を計算
SQL1 SELECT site_id, site_name, SUM(view) AS view, SUM(conversion) AS conversion FROM site AS T1 INNER JOIN site_view AS T2 USING(site_id) GROUP BY site_id, site_name ORDER BY site_id LIMIT 10 OFFSET 0;
SQL2 SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view GROUP BY site_id) AS T2 USING(site_id) ORDER BY site_id LIMIT 10 OFFSET 0;
上記のSQL1,SQL2を検証します.
検証用のシェルを作成.

sql1.sql

\timing
SELECT site_id, site_name, SUM(view) AS view, SUM(conversion) AS conversion FROM site AS T1 INNER JOIN site_view AS T2 USING(site_id) GROUP BY site_id, site_name ORDER BY site_id LIMIT 10 OFFSET 0;
SELECT site_id, site_name, SUM(view) AS view, SUM(conversion) AS conversion FROM site AS T1 INNER JOIN site_view AS T2 USING(site_id) GROUP BY site_id, site_name ORDER BY site_id LIMIT 10 OFFSET 10;
・・・
SELECT site_id, site_name, SUM(view) AS view, SUM(conversion) AS conversion FROM site AS T1 INNER JOIN site_view AS T2 USING(site_id) GROUP BY site_id, site_name ORDER BY site_id LIMIT 10 OFFSET 90;
sql2.sql

\timing
SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view GROUP BY site_id) AS T2 USING(site_id) ORDER BY site_id LIMIT 10 OFFSET 0;
SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view GROUP BY site_id) AS T2 USING(site_id) ORDER BY site_id LIMIT 10 OFFSET 10;
・・・
SELECT site_id, site_name, view, conversion FROM site AS T1 INNER JOIN (SELECT site_id, SUM(view) AS view, SUM(conversion) AS conversion FROM site_view GROUP BY site_id) AS T2 USING(site_id) ORDER BY site_id LIMIT 10 OFFSET 90;

それぞれの時間を以下のコマンドで検証します.
psql -U postgres -f sql1.sql analytics | grep Time: | cut -d " " -f 2
psql -U postgres -f sql2.sql analytics | grep Time: | cut -d " " -f 2

以下が検証結果です。
実行ファイル 1回目 2回目 3回目 4回目 5回目 6回目 7回目 8回目 9回目 10回目 最小 最大 平均
sql1.sql 2314.365 2247.267 2331.978 2235.310 2244.249 2457.474 2531.733 2445.966 2614.957 2483.380 2235.31 2614.957 2390.6679
sql2.sql 1080.565 1041.092 1062.615 1019.743 1037.495 1031.203 1020.304 1049.538 1021.847 1043.459 1019.743 1080.565 1040.7861
と検証結果はこのようになりました。
sql2のほうが圧倒的です。(ここまででるのかw
ここからさらにWHERE句を付けより検証していきたいと思います。
とりあえずこの記事はここまで次回part2を記事化していきます。

2013年12月15日日曜日

postgresで連番のテストデータを作成

SQLの検証をしたくてテストデータを作成しようと
思ったのですが良い方法がないか検討しまとめました。

今回は親のテーブルに対して、1日毎にレコードが付く構造です。
以下テーブル用のSQLになります
-- サイト情報
CREATE TABLE site (
 site_id SERIAL,
 site_name TEXT,
 PRIMARY KEY(site_id)
);

-- サイト履歴
CREATE TABLE site_view (
 site_id NUMERIC(19, 0),
 date TIMESTAMP,
 view NUMERIC(19, 0), --  view数
 conversion NUMERIC(19, 0), -- コンバージョン数
 PRIMARY KEY(site_id, date)
);

サイトとサイトに対するview数とコンバージョン数のデータです。
Googleアナリティクスのデータみたいなものを集計したいのでこのような名称ですw

今回はこちらの2テーブルに以下の条件でデータを入れます.
1.siteテーブルには1000件のサイト情報を入れる.
2.siteテーブルには連番でサイト名を登録.
3.site_viewには過去1年間のレコードを入れる.
4.site_view#viewには必ず毎日1以上のレコードが存在する.
5.site_view#conversionには、view以下の数値が入る.
以上の条件で生成します。

-- 1000件のサイト情報を作成します。
INSERT INTO site(site_name) SELECT 'site' || generate_series(1, 1000);

-- 1年分のテストレコードの作成
INSERT INTO site_view(site_id, date, view) SELECT site_id, (current_date - (generate_series(1, 365) || ' days')::INTERVAL) AS date, TRUNC(random() * 1000) AS view FROM site;

-- 1年分のconversionデータの作成
UPDATE site_view SET conversion = TRUNC(random() * view);
これで完了です。
generate_seriesを利用することで連番が作成できるのでこの機能を利用しました
またgenerate_seriesを利用し日付を1年間-1ずつすることで簡単に1年分の日付を1行で
記載が可能です。

日本の地ウイスキー通販についてpart.2

前日に引き続き記載
ここからはあまり扱っているバーも少なく通販で買うのがよさそうな
ものが中心になります。

思っている以上に多く苦戦中


札幌酒精工業


北海道に蒸留所を持つメーカーです
文字通り出すウイスキーはサッポロウイスキーです
お手頃なのでお試しあれ



笹の川酒造


チェリーウィスキーと呼ばれる種類を出荷されているメーカーです。
ピュアモルトを主流とし、1.8リットルの一升瓶サイズもあるので
1本で長持ちします。
 

東亜酒造


埼玉県羽生市にある会社です。秩父で蒸留された原酒を使用しているみたいです。
買ったのですが、まだあけていない・・・


若鶴酒造

富山にある酒造まだ試したことないが20年ものが気になる・・・
おそらくバーではまずないと思われます。


モンデ酒造


山梨にありワインが中心ですが、ひっそりとウイスキーが作られています。
容器の細工が綺麗です
ブランデーもあるのが気になります。


まだまだあるので@1〜2回にわけ記載します。

2013年12月14日土曜日

日本の地ウイスキー通販について

表題の通り、日本の地ウイスキーに通販についてまとめました。
メモしないとリンク失うw

日本には主にサントリーから始まり、さまざまな酒造でウイスキー造りが始まりました。
そんななか今も直 地ウイスキーを作っている情報をまとめます。

以下の3点の条件を満たしている点でまとめています。
1.現在購入可能であること
2.通販可能なこと
3.おそらくバーにある

サントリー

言わずと知れたサントリー有名なのは以下の

山崎

おなじみのお酒です。

ちなみに山崎シリーズで一番高い山崎は「山崎25年」です。10万超えです。
一度は飲むことをお勧めします。(高いけれどバーでお試しをw


ニッカウヰスキー

最近CMやっていますね。
ブラックニッカなど様々ものがあります。
ここでお勧めは、余市と宮城2つのシングルモルトです。
現地に、工場見学があるのですが北海道余市の工場見学が特によいです。

キリンディスティラリー

富士山麓が主な商品となります。
輸入が主で自社製品は少ないです。(残念
でも18年物があり飲んでみる価値はあります。これならギリギリバーにもあると思います。

 長くなるので何回かに分けて投稿します。

2013年8月7日水曜日

JQueryライクなNode.jsを実行する方法(cheerio編)

Node.jsでJqueryライクな処理を行いたく記載
2013/08/07現在、node.jsのJqueryが利用できない?(利用の仕方がわからない)
npm install jquery
が途中で下記のエラーとなるため代替案を模索.

npm http 304 https://registry.npmjs.org/bindings

npm http 304 https://registry.npmjs.org/bindings

> contextify@0.1.6 install /Users/genya/node_modules/jquery/node_modules/contextify
> node-gyp rebuild

npm http 304 https://registry.npmjs.org/cssom
npm http 304 https://registry.npmjs.org/cssstyle
xcode-select: Error: No Xcode is selected. Use xcode-select -switch <path-to-xcode>, or see the xcode-select manpage (man xcode-select) for further information.

gyp: Error 2 running xcodebuild
gyp ERR! configure error 
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:424:16)
gyp ERR! stack     at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:789:12)
gyp ERR! System Darwin 12.4.0
gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/genya/node_modules/jquery/node_modules/contextify
gyp ERR! node -v v0.10.15
gyp ERR! node-gyp -v v0.10.6
gyp ERR! not ok 
npm ERR! weird error 1
npm ERR! not ok code 0
上のエラーがよくわからないので対策を考えるのではなく代替案を調べていると
行き着いた先が、cheerio を利用する方法です。


環境
環境情報 構築日 ソフトウェア
Node 2013/08/07 v0.10.15


Node.jsをインストールした状態で、下記コマンドを実行
npm install request
npm install cheerio
上記コマンドが成功したら、インストールは完了

下記のないようのy.jsファイルを作成
var request = require("request");
var cheerio = require("cheerio");
var requestUrl = "http://yahoo.co.jp";
request({url: requestUrl}, function(error, response, body) {
 if (!error && response.statusCode == 200) {
   $ = cheerio.load(body);
  var title = $("title").text();
        console.log(title);
 }
});
これで動作(コマンド:node y.js)すれば「Yahoo! JAPAN」の文字が現れます。
応用すれば様々な内容に応用可能です。
自分独自のクローラーが有力です。

2013年7月16日火曜日

Chrome アドオン開発 No.1 ポップアップアドオンを作成

Google Chromeのアドオンを作ろうと思い調べたことをメモしていきます。
様々なことが可能なアドオンですが、複雑のため勉強がてらのまとめとなります。
動作イメージは下記です。

アドオン動作イメージ

簡単なポップアップですが楽ではありますが
マニュアルを自力で読解は面倒です。


環境
環境情報 構築日 ソフトウェア
Google Chrome【mac版】 2013/07/16 27.0.1453.116

とりあえずアドオンにアイコンが必要なのでicon.pngを用意
19×19のサイズで用意します。

icon.png




続いてマニフェストファイル「manifest.json」を用意します

{
  "name": "アプリ名称",
  "manifest_version" : 2,
  "version": "1.0", 
  "description": "アドオンの説明.", 
  "browser_action": { 
    "default_icon": "icon.png", 
    "default_title": "サンプル", 
    "default_popup": "popup.html"
  },
  "permissions": [
    "http://localhost/"
  ]
}

上記がマニフェストとなる。
「manifest_version」はおまじないで無視した方が良い
chromeのバージョンに依存するみたいである。

マニフェストファイルでの注目点は下記2つである

  • browser_action
    • 指定したアイコンをクリックするとポップアップが洗われる
  • permissions
    • 有効なサイトを固定する

permissionsはセキュリティの意味で利用しますがすべてのサイトが
対象の場合は必要ありません。

続いてpopup.htmlとなります。

<html>
<style>
body {
  min-width:357px;
  overflow-x:hidden;
}
</style>
<body>
adin test
</body>
</html>


これで準備が完了です。
続いて、chromeで動作させるための行いかたです
「設定」>>「機能拡張」>>「パッケージ化されていない拡張機能を読み込む」
を選択肢、上記3ファイルが保存されているディレクトリに移動させれば
アドオンが動作します。

とりあえず第1弾のアドオン開発メモです。

2013年7月6日土曜日

postgresで一次テーブルをトランザクションで利用

postgresの一次テーブルについてのメモ
一次テーブルを利用しようとしたが仕様がいまいち
わからなかったのですこしまとめました。
大きく2点のまとめです。
1.一次テーブルをとりあえず作ったらどのタイミングで消えるのか
2.BEGIN,COMITのトランザクション間で一次テーブルを利用するにはどうすれば良いのか

この2つについて記載いたします。


環境
環境情報 構築日 ソフトウェア
CentOS 6.3 2013/07/06 postgresql8.4



1.一次テーブルをとりあえず作ったらどのタイミングで消えるのか
こちらについては、とりあえず一次テーブルを作る意味合いのメモです。


$ psql 
-- 以下SQL文を記載

-- 一次テーブルを作成
CREATE TEMP TABLE temptable1(id numeric(9,0));

-- この時点ではtemptable1は残っている
INSERT INTO temptable1 VALUES(1);
-- この時点ではtemptable1は残っている
BEGIN;
INSERT INTO temptable1 VALUES(2);
INSERT INTO temptable1 VALUES(3);
-- この時点ではtemptable1は残っている
SELECT * FROM temptable1;
COMMIT;
-- この時点ではtemptable1は残っている
SELECT * FROM temptable1;
-- この時点ではtemptable1は残っている
¥q
-- この時点でtemptable1は削除される
$ psql 

-- この時点でtemptable1は存在しない
¥d temptable1

と、上記のようになります。
特に意識せずに一次テーブルを作成すると、¥qで全体を抜けるまで
一次テーブルが有効です。ちなみにコンソールを2つ表示し
それぞれpsqlコマンドで同じDBに入っても作った方意外からは見えません。
これが一次テーブルです。


2.BEGIN,COMITのトランザクション間で一次テーブルを利用するにはどうすれば良いのか
こちらの使い方を自分で使いたかったのでまとめました。

$ psql 
-- 以下SQL文を記載

BEGIN;
-- 一次テーブルを作成 COMMIT DROPオプションがつきます
CREATE TEMP TABLE temptable1(a numeric(9,0)) ON COMMIT DROP;

-- テーブルが存在します。
¥d temptable1

COMMIT;

-- テーブルが存在しません。
¥d temptable1

このようにトランザクションを張る場合は、COMMIT DROPが有効です。
重たい動作をされる際にご利用ください。

CentOS6にmonoをインストール

C#などの.NET系をLinuxで利用するためにmono projectがあります
2013/07/06現在最新版が3.0.12でありまたこちらをCentOSにインストールしようと思ったのでメモします。
ソースコードは70M程度の容量があるのでサイズに注意です

環境
環境情報 構築日 ソフトウェア
CentOS 6.3 2013/07/06 yum,make

結構いろいろ必要なのでOSをインストールしてすぐの想定で行います
$ su -
# とりあえずdev環境を整えるために必要そうなものをインストール
$ yum install bison gettext glib2 freetype fontconfig libpng libpng-devel libX11 libX11-devel glib2-devel libgdi* libexif glibc-devel urw-fonts java unzip gcc gcc-c++ automake autoconf libtool make bzip2 wget
$ wget http://download.mono-project.com/sources/mono/mono-3.0.12.tar.bz2
$ bunzip2 mono-3.0.12.tar.bz2
$ tar xvf mono-3.0.12.tar 
$ cd mono-3.0.12.tar 
$ ./configure --prefix=/usr/local
$ make && make install
$ mono --version

手順自体は単純ですが、ちょっと面倒ですね。 大体の時間はMac上にVMを立てて動かしましたが10分程度でした。 とりあえず動かす環境ができたので実際にexeなど作って今度動作させる予定

2013年7月2日火曜日

deteコマンドの使い方

dateコマンドは日付を確認するための機能ですが思いのほかオプションが
あり覚えられないのでよく利用するものをメモ
自分でよく利用するのはyyyy/MM/ddなので原則こちらのフォーマットにあわせています.

主に自分で利用するのは、今日、昨日、今月末、30日前などがよく利用します.


dateコマンド例(yyyy/MM/dd)
目的 コマンド
今日 date +'%Y/%m/%d'
明日 date -d '1day' +'%Y/%m/%d'
昨日 date -d '1day ago' +'%Y/%m/%d'
月初 date +'%Y/%m/01'
月末 date +'%Y/%m/%d' -d "1 day ago `date +'%Y/%m/01' -d'1 month'`"
前月 date -d '1month ago' +'%Y/%m/%d'
前月末 date +'%Y/%m/%d' -d "1 day ago `date +'%Y/%m/01'`"
来月末 date +'%Y/%m/%d' -d "1 day ago `date +'%Y/%m/01' -d'2 month'`"
来月末 date +'%Y/%m/%d' -d "1 day ago `date +'%Y/%m/01' -d'2 month'`"
1年前 date +'%Y/%m/%d' -d '1 year ago'
30日前 date +'%Y/%m/%d' -d '30day ago'


ついでに簡単な時間も出してみます。


dateコマンド例(hh:mm:ss)
目的 コマンド
現在時刻 date +'%H:%M:%S'
1時間前 date -d '1hour ago' +'%H:%M:%S'
1時間後 date -d '1hour' +'%H:%M:%S'

dateコマンドは意外と利用するがよく利用するのをメモするべきですね

2013年6月23日日曜日

改行付きcsvのパース

csvからtsvへコンバートが欲しかったのですが、 改行コードが入っているcsvであったため楽にできませんでした。 csvは改行コードがある場合ダブルクォーテンションで囲まれているのが特徴です。
下記のサイトに改行コードが含んでいるcsvをパースする方法がperlありましたので こちら 改変しましてコード化しました。
csv2tsv.pl
#!/usr/bin/perl
use strict;
use warnings;
my $column = '';
while (my $line = ) {
    my $count = 0;
    $line .=  while ($line =~ tr/"// % 2 and !eof(STDIN));
 
    $line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/,/;
    my @values = map {/^"(.*)"$/s ? scalar($_ = $1, s/""/"/g, $_) : $_}
    ($line =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
    for $column (@values) {
        $column =~ s/\x0D\x0A|\x0D|\x0A//g;
        print $column, "\t";
    }
    print "\r\n";
}

上記をcsv2tsv.plとしてサンプルを作成いたしました。 test.csv
header1,header2,header3
test1,test2, "test,3"
"test
1",test2,test3 
上記が、サンプル用csvとなります。
cat test.csv | csv2tsv.pl
こちらのサンプルで改行付きcsvをパースできます。

2013年6月18日火曜日

postgresで累計グラフ用のデータを作成

postgresで累計グラフ(積み上げ折れ線グラフ)を作成するための集計を実施します。
使うようで使わない気がしますが、私では利用する頻度が多いのでメモ含め書き留めます。


今回は、あるシステムで6月の日付ごとにコストと集客人数を
入力したテーブルに対して6月の日毎のと累計を知りたいのが目的とします。
環境
環境情報 構築日 ソフトウェア
CentOS 5.6 2013/06/18 postgresql 8.4以降
今回利用するSQLではpostgresql 8.4以降でないと扱えない文法のため 8.4以上でお試しください。 まずは、お決まりのテーブルを作成
-- コスト、集客管理
CREATE TABLE report (
 date TIMESTAMP, -- 集計日
 cost NUMERIC(19, 0), -- コスト 
 person NUMERIC(19, 0) -- 集客人数
);

-- 日毎のデータ
INSERT INTO report VALUES
('2013/06/01', 100, 1),
('2013/06/02', 120, 3),
('2013/06/03', 150, 0),
('2013/06/04', 110, 6),
('2013/06/05', 130, 1),
('2013/06/06', 120, 4),
('2013/06/07', 160, 5),
('2013/06/08', 190, 7),
('2013/06/09', 100, 1),
('2013/06/10', 110, 9),
('2013/06/11', 100, 8),
('2013/06/12', 100, 5),
('2013/06/13', 130, 4),
('2013/06/14', 120, 3),
('2013/06/15', 100, 6),
('2013/06/16', 100, 1),
('2013/06/17', 110, 0),
('2013/06/18', 100, 0),
('2013/06/19', 170, 1),
('2013/06/20', 100, 2),
('2013/06/21', 100, 6),
('2013/06/22', 190, 7),
('2013/06/23', 100, 9),
('2013/06/24', 100, 1),
('2013/06/25', 190, 8),
('2013/06/26', 100, 6),
('2013/06/27', 120, 7),
('2013/06/28', 120, 4),
('2013/06/29', 150, 2),
('2013/06/30', 110, 1);


上記のデータが元データです。 集計には「over」と呼ばれるWindow関数を利用します。

-- 集計用SQL
SELECT date, SUM(cost) over (order by date) AS cost, SUM(person) over (order by date) AS person FROM report;
        date         | cost | person 
---------------------+------+--------
 2013-06-01 00:00:00 |  100 |      1
 2013-06-02 00:00:00 |  220 |      4
 2013-06-03 00:00:00 |  370 |      4
 2013-06-04 00:00:00 |  480 |     10
 2013-06-05 00:00:00 |  610 |     11
 2013-06-06 00:00:00 |  730 |     15
 2013-06-07 00:00:00 |  890 |     20
 2013-06-08 00:00:00 | 1080 |     27
 2013-06-09 00:00:00 | 1180 |     28
 2013-06-10 00:00:00 | 1290 |     37
 2013-06-11 00:00:00 | 1390 |     45
 2013-06-12 00:00:00 | 1490 |     50
 2013-06-13 00:00:00 | 1620 |     54
 2013-06-14 00:00:00 | 1740 |     57
 2013-06-15 00:00:00 | 1840 |     63
 2013-06-16 00:00:00 | 1940 |     64
 2013-06-17 00:00:00 | 2050 |     64
 2013-06-18 00:00:00 | 2150 |     64
 2013-06-19 00:00:00 | 2320 |     65
 2013-06-20 00:00:00 | 2420 |     67
 2013-06-21 00:00:00 | 2520 |     73
 2013-06-22 00:00:00 | 2710 |     80
 2013-06-23 00:00:00 | 2810 |     89
 2013-06-24 00:00:00 | 2910 |     90
 2013-06-25 00:00:00 | 3100 |     98
 2013-06-26 00:00:00 | 3200 |    104
 2013-06-27 00:00:00 | 3320 |    111
 2013-06-28 00:00:00 | 3440 |    115
 2013-06-29 00:00:00 | 3590 |    117
 2013-06-30 00:00:00 | 3700 |    118
(30 行)


苦労してSQLをくまないと行けないと考えていましたがWindow関数で簡単にできました。 EC売り上げ集計や、広告レポートを集計するのに役に立ちそうです。

【mac】capistranoのインストール

macにcapistranoを利用したかったのでまとめました。
sudo等が必要なためCentOS分から一部を抜粋

環境
環境情報 ソフトウェア 必要込コマンド
Mac OS X Mountain Lion ruby sudo,curl
$ sudo mkdir /usr/local/src
$ cd /usr/local/src
$ sudo curl -O http://production.cf.rubygems.org/rubygems/rubygems-1.8.24.tgz
$ sudo tar xzovf rubygems-1.8.24.tgz
$ cd rubygems-1.8.24
$ sudo ruby setup.rb
$ sudo gem install capistrano

capistranoサンプル集【tomcat restart】

capistranoのサンプル集です。 普段利用しているものを少しメモ含めまとめました。
role :host, "test1.com", "test1.com" # サーバを指定複数の場合は,区切りで追記
set :application, "deploy.test" # アプリケーション名
set :ssh_options, :port => "22" # ポート指定
set :user, "admin" # sshでログインするユーザー(要sodo権限)

# tomcat 再起動
task :tomcat-restart, :roles => :host do
 sudo "/etc/init.d/tomcat5 restart"
 sudo "/etc/init.d/httpd restart"
end
単純ですが、意外と使えます。 実運用では、ロードバランサーがあると全tomcatが止まるので監視が飛ぶかもしれない ので要注意です。ご利用の際は、監視を受け取っている方にご連絡を

2013年6月17日月曜日

bashでfor next

備忘録となるがシェル(bash)でforを利用したカウンタを作る際に苦労したので
紹介

やりたいことは、JavascriptやC言語などでよくある
for (i = 0; i < 10; i+=2) {
 処理を記述
}

上記みたいなi+=2のfor文を作りたい


実際にシェルで記載

#!/bin/bash
for i in `seq 0 2 10`;
do
  echo "${i}"
done
上記で対応ができるbash的にはforはforeachみたいな役割なので 少々書き方が面倒だが便利に行えます。

2013年5月6日月曜日

最小二乗法を使用して、指数近似を解く

最小二乗法は通常直線の近似を求めるための手法です。 今回解く、曲線は 非線形曲線
こちらです、よくあるy=a×exp(b)これが求める式となる。
曲線
この式をベースに式を変形しといていきます。
ここにはlogの性質を利用します。
ログの性質
ログを変換することで最終的に「ln(y)=ln(x)+bx」となるこれで
最小二乗法を解ける(y=ax+b)になりました。
非線形最小二乗法
最終的に上記の様な式が立てれる

この式を実施する上で問題となるのはlogを使う点です。
log(x)を解く場合にx=0は入れることができません
log(0)が解けないのが難点で、一部値が利用できない可能性がああります。
そのため、0が来るような値を利用しないことをお勧めいたします。

2013年4月25日木曜日

Linuxでmailに添付ファイルを付ける【uuencodeを利用しない】

Linuxでシェルを作っていると、メールを送信すること
またメールに、添付ファイルを付けたくなった
既存のコマンドだけで可能な限り対応できないかと模索し
シェルを作成。
よく目にするのは、uuencodeコマンドを利用する方法だが
今回は動作環境の事情もあり、該当のコマンドを利用しない方帆を記載

sendmailコマンドを利用し対応、少し汎用性は付けたが
ほぼ基礎のみ比較的簡単に添付ファイルが送付可能
複数のファイルには非対応のため注意が必要

原理は、mailはテキストを特定の書式で送るのが原理のため
書式を手動で作成すれば良い

メールの仕様書を読めばより理解が深まるだろう

環境
環境情報 構築日 ソフトウェア 必要込コマンド
CentOS 5.6 2013/04/25 なし sendmail


#!/bin/bash

############################
## メール添付ファイルスクリプト
## コマンドラインから添付付きメールを送信するスクリプトです.
## ※日本語部分対応のため、完全ではございません.
##
## mail.sh {fromアドレス} {toアドレス} {タイトル} {本文} {添付ファイル名}
##
############################

## 初期化
from_address=$1
to_address=$2
subject=$3
mail=$4
TMP_FILE='mail.tmp'
boundary=`date +%Y%m%d%H%M%N`
content_type=`file --mime $1 | cut -d' ' -f2`
filename=`echo $5 | sed -e "s/.*\/\(.*$\)/\1/"`

## メール情報付与
echo "From: $from_address" > $TMP_FILE
echo "To: $to_address" >> $TMP_FILE
echo "Subject: $subject" >> $TMP_FILE
echo "MIME-Version: 1.0" >> $TMP_FILE
echo "Content-type: multipart/mixed; boundary=\"----$boundary\"" >> $TMP_FILE
echo "Content-Transfer-Encoding: 7bit" >> $TMP_FILE
echo "" >> $TMP_FILE
echo "This is a multi-part message in MIME format." >> $TMP_FILE
echo "" >> $TMP_FILE

## 本文
echo "------$boundary" >> $TMP_FILE
echo "Content-type: text/plain; charset=iso-2022-jp" >> $TMP_FILE
echo "Content-Transfer-Encoding: 7bit" >> $TMP_FILE
echo "" >> $TMP_FILE
echo "$main" >> $TMP_FILE
echo "" >> $TMP_FILE

## ファイル情報(base64で送信)
echo "------$boundary" >> $TMP_FILE
echo "Content-type: $content_type" >> $TMP_FILE
echo " name=$filename" >> $TMP_FILE
echo "Content-Transfer-Encoding: base64" >> $TMP_FILE
echo "Content-Disposition : attachment;" >> $TMP_FILE
echo " filename=$filename" >> $TMP_FILE
echo "" >> $TMP_FILE
cat $5 | base64 >> $TMP_FILE
echo "" >> $TMP_FILE
echo "------$boundary--" >> $TMP_FILE

## メールを送信
sendmail -i $to_address < $TMP_FILE

## 一時ファイルを削除
rm -f $TMP_FILE

exit 0

多少便利ぐらいで使う用途が限定されるが 意外と便利である 検証中に尽き動作保証できないが雰囲気が理解いただけるかと思います。

2013年4月21日日曜日

最小二乗法をpostgresで説く

postgresにも数学用の関数がいくつか用意されています。
こちらを利用し、最小二乗法が実現可能です。
ただし、作成できるのは線形(y=ax+b)のみなので利用用とは初級では限界があるかもしれません。
でも出来るだけでもありがたい。

環境
環境情報 構築日 ソフトウェア
CentOS 5.6 2013/04/20 postgresql 9.2
まずは、テーブルを作成
-- データ格納用テーブル.
CREATE TABLE target(
date TIMESTAMP, --  日付
sales NUMERIC(19, 0) -- 値
);
続いてデータを作成
INSERT INTO target VALUES('2013/01/01', 200);
INSERT INTO target VALUES('2013/01/02', 300);
INSERT INTO target VALUES('2013/01/03', 400);
INSERT INTO target VALUES('2013/01/04', 500);
INSERT INTO target VALUES('2013/01/05', 600);
INSERT INTO target VALUES('2013/01/06', 700);
INSERT INTO target VALUES('2013/01/07', 800);
INSERT INTO target VALUES('2013/01/08', 900);
INSERT INTO target VALUES('2013/01/09', 1000);
INSERT INTO target VALUES('2013/01/10', 1100);
INSERT INTO target VALUES('2013/01/11', 1200);
INSERT INTO target VALUES('2013/01/12', 1300);
INSERT INTO target VALUES('2013/01/13', 1400);
INSERT INTO target VALUES('2013/01/14', 1500);
INSERT INTO target VALUES('2013/01/15', 1600);
INSERT INTO target VALUES('2013/01/16', 1700);
INSERT INTO target VALUES('2013/01/17', 1800);
これで利用準備が整いました
では今回解く式はy=ax+bです。
日付は、日にちと考え、年月を集約します
xを日付、yを値とすると
インサートしたデータを利用すると式は
y=100x+100ができるはずです。
SQLを作成します。
-- 傾き(a)にあたる部分を取得
SELECT regr_slope(sales, to_char(date, 'dd'):: integer) FROM target ;
-- 切片(b)にあたる部分を取得
SELECT regr_intercept(sales, to_char(date, 'dd'):: integer) FROM target ;
今回のデータは参考用のためきれいな値が求まりましたが もっと複雑なのも大丈夫です。 今回利用した集約関数(postgresマニュアル参照)では下記の説明がなされています
regr_intercept(Y, X)(X, Y)の組み合わせで決まる、線型方程式に対する最小二乗法のY切片。
regr_slope(Y, X)(X, Y)の組み合わせで決まる、最小二乗法に合う線型方程式の傾き。

postgresql 9.2のインストール

CentOS 5.6を使用しpostgresql 9.2をインストールする構築手順書

環境
環境情報 構築日 ソフトウェア 必要込コマンド
CentOS 5.6 2013/02/01 postgresql yum
$ yum -y install ruby ruby-devel ruby-irb ruby-rdoc ruby-libs

$ su -
$ cd ~/
$ mkdir download
$ cd download

$ wget http://yum.postgresql.org/9.2/redhat/rhel-5-x86_64/pgdg-centos92-9.2-5.noarch.rpm
$ rpm -ivh pgdg-centos92-9.2-5.noarch.rpm
$ yum clean packages
$ yum install postgresql postgresql-server
$ /etc/init.d/postgresql-9.2 initdb
$ /etc/init.d/postgresql-9.2 start
とりあえずこれでインストールができる。

2013年4月17日水曜日

最小二乗法を解く

x,yの複数の点から最も近い方程式を導く方法として 最小二乗法があります。 最小二乗法を解く上でy=ax+bを解くサイトは多々みましたが あまり実際の値で行っているところがなかったのでメモ y=ax+bの式を計算から解いています。 最終a=1,b=0が解で得られます途中微分などの 知識も必要なためある程度の概念が必要になりますが参考までに

最小二乗法
今回のようなy=ax+bは線形と呼ばれ直線で表すことができます。 後々、非線形eやlogなどの解き方も記事にしていきます。

2013年4月14日日曜日

【Linux】capistranoインストール手順

CentOS 5.6を使用しcapistranoを利用可能にする構築手順書

環境
環境情報 ソフトウェア 必要込コマンド
CentOS 5.6 ruby yum
$ yum -y install ruby ruby-devel ruby-irb ruby-rdoc ruby-libs
$ cd /usr/local/src/
$ wget http://production.cf.rubygems.org/rubygems/rubygems-1.8.24.tgz
$ tar xzovf rubygems-1.8.24.tgz
$ cd rubygems-1.8.24
$ ruby setup.rb
$ gem install capistrano

【Linux】CentOSでPHP+sqliteを利用する

CentOS 5.6を使用しPHPでsqlite3を利用可能にする構築手順書

環境
環境情報 ソフトウェア 必要込コマンド
CentOS 5.6 php,wget wget
$ wget http://pecl.php.net/get/sqlite3-0.6.tgz
$ su -
$ yum -y install php httpd
$ tar xzf sqlite3-0.6.tgz
$ cd sqlite3-0.6
$ phpize
$  ./configure
$ vi sqlite3.c
$ wget -O php-5.3.3.tar.bz2 http://museum.php.net/php5/php-5.3.3.tar.bz2
$ tar zxvf php-5.3.3.tar.bz2
$ bzip2 -dc php-5.3.3.tar.bz2 | tar xvf -
$ cd php-5.3.3/ext/sqlite
$ phpize
$ ./configure
$ make
$ make install
$ vi /etc/php.d/sqlite.ini
$ echo "extension=sqlite3.so" /etc/php.d/sqlite.ini
$ /etc/init.d/httpd graceful