読者です 読者をやめる 読者になる 読者になる

psqlでSQLとメタコマンドを併用する

postgre

結論

実行するSQLとメタコマンドが記述されたファイルを用意する
※デリミタがタブ文字の場合は、「ターミナルで Ctrl+v を押してからタブ押下」

delete from zipcode_info;
delete from zipcode_info2;
\copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ','
\copy zipcode_info2 (pref_code, city_code, zipcode) from data2.csv with delimiter ','

psqlを実行する(上記で用意したファイルをsql.txtとして

psql -U user_name -h host_name -d db_name -f sql.txt -1 2>&1

事の始まり

https://oshiete.goo.ne.jp/qa/8159495.html
やりたいことは、対象テーブルの更新(レコードの削除+流し込み)
上との違いは、対象となるテーブルが複数あることくらい。

調べてみる

copy
http://qiita.com/egg_chicken/items/cec72bda3759f875285f

psql
https://www.postgresql.jp/document/9.1/html/app-psql.html

オプション「-c command」の説明を見ると...

このため、このオプションではSQLpsqlタコマンドを混在させることはできません。 これらを同時に使用するには、echo '\x \\ SELECT * FROM foo;' | psqlのようにパイプを使って文字列をpsqlに渡します(\\はメタコマンドの区切り文字です。)。
コマンド文字列が複数のSQLコマンドを含む場合、トランザクションを複数に分けるBEGIN/COMMITコマンドが明示的に文字列内に含まれない限り、それらのコマンドは1つのトランザクションで処理されます。


SQLとメタコマンドをパイプで渡せば、psqlで実行できそう

やってみる

こういうことはできない

psql -U user_name -h host_name -d db_name -c "delete from zipcode_info; \copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ','"

から...

echo "select * from zipcode_info;" | psql -U user_name -h host_name -d db_name

的なノリで

echo "delete from zipcode_info; \copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ','" | psql -U user_name -h host_name -d db_name

できた。
けど、これだとトランザクションが張れていないので…

echo "BEGIN; delete from zipcode_info; \copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ',' COMMIT;" | psql -U user_name -h host_name -d db_name

\copyのパースに失敗…
いろいろ試してみる

echo "BEGIN; delete from zipcode_info; \copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ',' \\ COMMIT;" | psql -U user_name -h host_name -d db_name
echo "BEGIN; delete from zipcode_info; \copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ',' \n COMMIT;" | psql -U user_name -h host_name -d db_name

タメだ…区切り文字が分からない…

もう一度調べてみる

psql
https://www.postgresql.jp/document/9.1/html/app-psql.html

オプション「-f filename」の説明を見ると...

対話式にコマンドを読み取るのではなく、filenameファイルをコマンドのソースとして使用します。 このファイルの処理が終了した後、psqlは終了します。 これは\i内部コマンドとほぼ同じ効力を持ちます。


オプション「-1」の説明を見ると...

fオプションを使用してpsqlスクリプトを実行する時、このオプションを併記すると、スクリプトをBEGIN/COMMITで囲み、単一トランザクション内でスクリプトを実行します。 これにより確実にすべてのコマンドが完全に成功するか、変更がまったく行われないかのいずれかになります。


これだ

もう一度やってみる

実行するSQLとメタコマンドが記述されたファイルを用意する

delete from zipcode_info;
\copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ','

トランザクション張る必要があるからオプション付けて

psql -U user_name -h host_name -d db_name -f sql.txt -1

できた(エラーが発生すると反映されない、トランザクションが効いてる

対象となるテーブルが複数ある場合は、複数のSQLとメタコマンドが記述されたファイルを用意して

delete from zipcode_info;
delete from zipcode_info2;
\copy zipcode_info (pref_code, city_code, zipcode) from data.csv with delimiter ','
\copy zipcode_info2 (pref_code, city_code, zipcode) from data2.csv with delimiter ','

psqlコマンドを実行してみる

psql -U user_name -h host_name -d db_name -f sql.txt -1 2>&1

できてる

仮にできなかったら

psqlコマンドで個々のSQLやメタコマンドは実行できるから、トランザクション機能をどこかで補完する必要がある。
オブサーバ的なテーブルで参照先のテーブルを切り替えることで、トランザクション機能を肩代わりすれば問題ない。
本来想定していたテーブルと合わせてミラーリング用のテーブルを用意し、更新処理が正常に終わったら参照するテーブルを切り替える。

1つのサーバで複数の開発環境をつくる

linux

前提条件として…

  • php(phpenv,composer導入済み)、apacheで稼働
  • 何かしらのフレームワークを利用(Fuelを想定)
  • バージョン管理されてる(gitbucketを想定)

リソースの取得

まずは、管理リソースを。

# cd /var/www/
# git clone -b develop http://~.git 開発用ディレクトリ
# chown -R user:user 開発用ディレクトリ


次に、管理外リソースを。

// composer利用に伴いバージョン調整
$ cd /var/www/開発用ディレクトリ
$ phpenv install 5.6.15
$ phpenv local 5.6.15
$ phpenv versions // バージョン確認

// composerパッケージの取得
$ php composer.phar self-update
$ php composer.phar install


↑2つ(管理/管理外リソースの取得)はコピーで済むなら、それでも。

# cd /var/www/
# cp org_dir 開発用ディレクトリ

開発者固有の設定

git等

$ vi 開発用ディレクトリ/.git/config
// 以下を追記
[user]
        name = aitaka
        email = aitaka@~.co.jp

$ git remote set-url origin http://aitaka@~.git

Apache(バーチャルホスト)の設定

いろいろやり方はあるけど、今回は「違うポートで違うサイトを運営する」
バーチャルホストの例 - Apache HTTP サーバ バージョン 2.2


ポートの利用状況について調べる

$ netstat -anp | grep ポート番号

参考
Linuxでアプリケーションが使用中のポート番号を調べる - 日々の報告書


バーチャルホストを追加する

# vi /etc/httpd/conf/httpd.conf
// 以下を追記
// ポート番号を890としたとき
Listen 890
<VirtualHost *:890>
    DocumentRoot /var/www/開発用ディレクトリ/public/
    ServerName dev1
    <Directory /var/www/開発用ディレクトリ/public>
      AllowOverride All
      Options Indexes FollowSymLinks
    </Directory>
</VirtualHost>

# service httpd restart

参考
ポートベースのバーチャルホストを設定する - MogLog
いまさら聞けない!? Web系開発者のためのサーバ知識(3):Apacheで仮想ホストを動かそう (1/3) - @IT

firewallの設定

通過許可ポートの追加

# vi /etc/sysconfig/iptables
// 以下を追記
// ポート番号を890としたとき
-A INPUT -m state --state NEW -m tcp -p tcp --dport 890 -j ACCEPT

# service iptables restart

参考
iptablesの設定方法 – さくらのサポート情報

エッセイ

今に始まったことではないけれど、最近、過去の自分(1,4,7,8年前とか)を振り返って、何て酷いことをしていたんだろうと思うことが多々ある。

これはさまざまな視点から言えることで、例を挙げれば、価値観や技能、勉学や人付き合いとまぁいろいろある。
価値観に関して言えば、あの当時は何でああいう考え方(価値の優先順位)をしていたんだろうとか。

特に、価値観は最も重要だ。なぜなら、価値観はその他の要素に多大な影響を与える。それらを決定づけてしまうほどに。

ここ2-3年で、さまざまなことが原因となり(テレビ(比喩だよ)の見過ぎということはあるかもしれない)、価値観が激変してしまった。
切り替わったというよりは、異なるモノが食い込んできた感じかもしれない。掻き乱されているだけなのかもしれない。
そんなこんなで、現在の価値観とは相容れない、過去の地続きにいる自分の現状に愕然としつつ、すっかり意気消沈している。

けれどこう悲観してばかりもいられないわけで、どこかで折り合いを付ける必要がある。
今一度、新たに手にしたはずの価値観からこの状況を眺めてみる。
本当に価値観が変わったのであれば、この状況から何かしらの意味を見い出せる(見い出せないのであればそれは...)。

形はどうあれ、ここまでの過程を感覚的に知っているのは自分だけであることが分かってくる。
過去の自分との差分を認識できたということは、方向はともかく確実に進んできたということを示している。
当時は何の疑問に思わなかったことを今は問い続けている。

「傍から見れば...」という問題はあるけれど、それよりも重要なことがあると思っていきたい。

過去、及びその地続きにある現状に絶望する自分を越えていけ。

gitでよく使うの

git

clone

git clone -b ブランチ名 リモートリポジトリのURL [ローカルリポジトリ名]

remote

# リモートリポジトリ一覧
git remote -v

# リモートリポジトリ追加
git remote add リモートリポジトリ名 リモート先(URLにユーザ名を含めたもの、「http://aitaka@~.git」的な)

# リモートリポジトリ設定
git remote set-url リモートリポジトリ名 リモートリポジトリのURL

# リモートリポジトリ削除
git remote rm リモートリポジトリ名

branch

# 作成及び移動
git checkout -b ブランチ名

# ローカルブランチの削除
git branch -d ブランチ名

# リモートブランチの削除(空ブランチのpush)
git push origin :ブランチ名

log

# ログ特定
git log --grep='コミットメッセージに含まれるキーワード'

# 差分表示
git log -p

diff

# ワークツリーとステージ領域
git diff

# ワークツリーと最新コミット
git diff HEAD

add

# 一斉追加
git add .

commit

# 簡易コミット
git commit -m コミット概要

reset

# コミットのみ取り消し(コードは変わらず)
git reset --soft コミットID

# コード修正/コミットの取り消し
git reset --hard コミットID

merge

# マージした記録を残す
git checkout ブランチ名1
git merge --no-ff ブランチ名2

rebase

# コミットの統合(対象コミットは、最新コミットからn個遡ったもの)
git rebase -i HEAD~n
# 統合するコミットIDのpickをfixupに書き換える
# 編集エディタを保存して終了すると、上記で編集したコミットが統合されている(なかったことになる)

push

git push リモートリポジトリ名(originとか) ローカルブランチ名:リモートブランチ名

# ブランチが同じ場合
git push リモートリポジトリ名(originとか) ブランチ名

pull

git pull リモートリポジトリ名(originとか) リモートブランチ名:ローカルブランチ名

# ブランチが同じ場合
git pull リモートリポジトリ名(originとか) ブランチ名

postgresでデータの流し込み

postgre

データを流し込む方法として、
ダンプ/リストアを使う方法と、エクスポート/インポートを使う方法をメモ。

ダンプ&リストア

# ダンプ
# テーブル定義のみダンプしたい場合は「-s」、データのみダンプしたい場合は「-a」を付ける
# 下記コマンドは、データのみダンプする場合
pg_dump [-h ホスト名] -U ユーザ名 -a -t テーブル名 データベース名 > data.sql

# 適時ダンプファイルを修正(ユーザ名の置換とか)

# リストア
# 単一トランザクション内でスクリプトを実行したい場合は「-1」を付ける
psql [-h ホスト名] -d データベース名 -U ユーザ名 -f data.sql -1


ちなみに、psqlSQLファイルを実行するコマンドなので、下記のようなファイルを別途用意してもいい。

create table city (
	city_id serial PRIMARY KEY NOT NULL,
	country_code text NOT NULL,
	pref_code text NOT NULL,
	pref_name text NOT NULL,
	city_code text NOT NULL,
	city_name text NOT NULL
);

(略)

エクスポート&インポート

# エクスポート
psql [-h ホスト名] -d データベース名 -U ユーザ名 -A -F, -c "select * from テーブル名" > data.csv
psql [-h ホスト名] -d データベース名 -U ユーザ名 -A -F $'\t' -c "select * from テーブル名" > data.tsv

# csv/tsvファイルの編集(data.csv/tsvのカラム名/レコード数に関する記述を削除)

# インポート
psql [-h ホスト名] -d データベース名 -U ユーザ名 -c "\copy テーブル名 (カラム1, カラム2, ...) from data.csv with delimiter ','"
psql [-h ホスト名] -d データベース名 -U ユーザ名 -c "\copy テーブル名 (カラム1, カラム2, ...) from data.tsv with delimiter '(ターミナルで 「Ctrl + v + Tab」)'"

# ちなみに、コマンド文字列(「-c」に続く文字列)が複数のSQLコマンドを含む場合、それらのコマンドは1つのトランザクションで処理される
# トランザクションを複数に分ける場合は、BEGIN/COMMITコマンドを明示的に追記する

古いAndroidアプリをバージョンアップすることになった人へ

Android

はじめに

eclipseで作成されたAndroidアプリの開発環境の構築手順です。
利用しているライブラリによって、多少作業が増えたり減ったりすると思います。

Android Studio」に移行できた人は読む必要がないので、戻るボタンをどうぞ。
お察しの通り、「Android Studio」の話は出てきません(移行を試みましたが…)。

1. 「eclipse with adt」のダウンロード

本家のダウンロードページが見つからないので、別途提供元を探す必要がある。
http://www.cutt.jp/books/978-4-87783-351-0/supp/chap00_ADT-gt-and-start.htmlからダウンロードする。

パスが長すぎる場合、解凍時に問題が発生する(「エラー 0x80010135 パスが長すぎます」が発生する)ため、ダウンロード先は「C:\(ドライブ直下)」等を指定する。

2. 「SDK Manager」で各ツールをインストール

アプリを動かすのに最低限必要なツール(「Android4.4」「Google API」「usb driver」等)をインストールする。

3. プロジェクトをインポート

バージョン管理の有無によって対応が異なる。

  • gitbuket等でバージョン管理されていない場合
    http://www.adakoda.com/android/000220.htmlに倣って、該当ディレクトリのインポートを行う。
    ちなみに、gitbucket等でバージョン管理したい場合は、
    [Git Repository Exploring](Perspective)を開いて、「Clone a git repository」をクリックする。表示されるウィンドウにしたがって、作成済みのリモートリポジトリに関する情報(http  clone url、ユーザ名、パスワード等)と、作成するローカルリポジトリの宛先を入力する。
    上記で作成したローカルリポジトリと該当プロジェクトを関連付けるため、該当プロジェクトを右クリックして[Team][Share Project…]を選択する。表示されるウィンドウで、上記で作成したローカルリポジトリを指定する。
    管理対象としないリソース(/bin・/gen等)を.gitignoreに追記する。
    プッシュする際に、Gitに関する情報(ユーザ、メールアドレス)を設定すれば完了。

  • gitbucket等でバージョン管理されている場合
    メニュータブから[File][import][Git][projects from git]を選択する。表示されるウィンドウにしたがって、既存のリモートリポジトリに関する情報(リモート先、ユーザID/パスワード)を指定する。
    その他の画面は、デフォルトのまま「next」をクリックしていけば完了。

    A.01. Git リポジトリからのプロジェクトのインポート · mixi-inc/AndroidTraining Wiki · GitHub

4. 「SDK Manager」でインストールできない各ツールをダウンロード&インポート

基本的には、前開発者が利用していたものを共有してもらう。
それができないようであれば、本家またはその他の提供元からダウンロードする。
バージョンによって配布方法やAPIが変更されるため、そこを踏まえたうえでダウンロードを行う必要がある。

例. 「Google Play Services」をダウンロード&インポート
google maps api」を利用しているアプリの場合、「google play services(端末にインストールされている「Google Play 開発者サービス」というAPKの機能を呼び出すためのインターフェース群)」が必要になる。

  1. ダウンロード

    バージョンによって、「google play services」の中身が異なる。
    http://qiita.com/komitake/items/f25191ac61292d1d095e
    あるバージョンから、「libproject」がなくなっている。
    http://stackoverflow.com/questions/37310684/missing-sdk-extras-google-google-play-services-libproject-folder-after-updat
    また、あるバージョンから、いくつかのパッケージが廃止されている。
    http://onlineconsultant.jp/pukiwiki/?com.google.android.gms.location.LocationClient%E3%81%8Cimport%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84

    最新バージョンをダウンロードして実装側でその差分(中身が違うとかAPIが変更されたとか)を埋めるか、
    前開発時に利用していたバージョンをダウンロードしてそのまま利用するか。

    今回は後者で対応する。
    旧バージョンのダウンロードリンクを利用して、該当バージョンを取得する。
    http://stackoverflow.com/questions/37310684/missing-sdk-extras-google-google-play-services-libproject-folder-after-updat
    http://stackoverflow.com/questions/20982533/how-to-download-older-google-play-services?noredirect=1&lq=1

  2. インポート
    [ファイル][新規][その他][Android][既存コードからのAndroidプロジェクト]を選択する。
    表示されるウィンドウで、「プロジェクトをワークスペースにコピー」にチェックを付け、「google-play-services_lib」を指定して、対象ライブラリをプロジェクトとしてインポートする。

    「Package Exploer」の「google_play_services_lib」を右クリックし、[Properties][Android][Project build target]を選択する。該当するAPIにチェックを入れる。

    「Package Exploer」の該当プロジェクトを右クリックし、[Properties][Android][Project build target]を選択する。「Google API」にチェックし、「Library」に上記でインポートした「google_play_services_lib」を追加する。 

5. 4のツール関連の設定

認証周りで作業が必要になったりする。

例.  「Google Maps APIキー」利用に関する設定
Google Developers Console(https://console.developers.google.com/?hl=JA)」にログインする。
「認証情報」より対象のAPIキーをクリックし、パッケージ名とフィンガープリントの追加を行う(フィンガープリントは、[Window][preference][Android][Build]から確認する)。

6. エラー対応

逐一調べていくしかない
http://shirokai.hatenablog.com/entry/eclipse-exclamation

一見意味のにないように思えて、実際にやってみると解決してしまうことがある。
上の作業でいえば、ライブラリの紐づけを一度外してもう一度付けたら…(もうよく分からない)。

7. この後

eclipse
http://aitaka.hatenablog.com/entry/2016/12/10/174504

基本(ライフサイクルとかContextとか)
http://www.atmarkit.co.jp/ait/articles/0901/19/news122.html
http://qiita.com/tyfkda/items/bbb77a0e5a97eda9d4b6
http://textdrop.net/soft/android-avoiding-memory-leaks/

おわりに

泥臭さ

EclipseWithADTに関するTips

Android

plugin

settings


  • [General][Appearance][Color Theme] 「Solarized dark」

  • 文字
    [General][Appearance][Colors and Font] 「フォントConsolas、サイズ10」

  • 行数/スベース
    [General][Editors][Text Editiors] 「show line number/show space character」にチェック

  • 補完
    [Window」][Preferences][Java][Editor][Content Assist] 「自動有効化遅延」の値を80、
    Javaの自動有効化トリガー」を「.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_」

function

  • Quick Access
    とりあえずここにキーワード入れれば、何かしらがヒットする

  • Outline
    該当クラスの構成がツリー形式で表示される

  • Bookmark
    手掛かりとなる箇所に残していく
    行数右クリック[Add Bookmark...]

  • Log cat
    ログ

keybind

  • 名前変更
    Alt + Shift + r

  • ファイル/リソース検索
    Ctrl + Shift + r

  • ファイル(ある文字列含む)検索
    Alt + a + f

  • クラス/インタフェース等の検索
    Ctrl + Shift + T

  • カーソル位置のクラス、インタフェース、変数等の宣言場所へ移動
    F3

  • 呼び出し階層(呼び出し先一覧)を開く
    Ctrl + Alt + h

  • カーソル位置のクラスの継承関係を表示

    F4

  • 戻る
    Alt + ←

other

  • 端末の安全な取り外し方
    Android 端末側の設定で、[開発][USBデバック]のチェックマークを外す