Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2722

HTTPリクエストと(Postgre)SQLを自動化するスクリプトを書いてみた

$
0
0

ローカル環境において、手動でHTTPリクエストや(Postgre)SQLを実行するのが辛くなってきたため、それらを自動化するBashスクリプトを書いてみました。
今回はこのスクリプトを解説いたします。

GitHubリポジトリはこちらです

想定している環境

  • ローカル環境
  • DBサーバ(PostgreSQL)がDocker上に存在

必要なライブラリのチェック

スクリプトではdocker、psql、jq、curlを使用しているため、これらがインストールされているかをチェックします。
各ライブラリの名前を、for文のinに列挙しています。
whichコマンドでエラーが出力された場合、usage()を呼び出し、標準出力は捨てています。

function usage(){echo"please install docker, psql, jq, and curl"exit 1
}# check requirementsfor libName in docker psql jq curl;do
  which $libName>$DEVNULL|| usage
done

(テスト用)既存のPostgreSQLコンテナの削除

スクリプトのテスト用に作成したDBコンテナがあれば削除します(実際には既存のDBコンテナが立っているはずなので、この処理はコメントアウトされるでしょう)。
docker ps -aで、指定の名前のコンテナが存在するかを0or1で取得します。空白が入るためsedで除去しています。
コンテナが存在した場合、停止と削除を実行します。

# remove existing containerexist=$(docker ps -a | grep$NAME | wc-l | sed's/ //g')if[[$exist= 1 ]];then
  docker stop $NAME>$DEVNULL&& docker rm$NAME>$DEVNULLecho"existing container $NAME removed"fi

(テスト用)PostgreSQLコンテナの起動、疎通が確認できるまで待機

スクリプトのテスト用に、PostgreSQLのコンテナを起動します(実際には既にDBコンテナが立っているはずなので、この処理はコメントアウトされるでしょう)。
起動直後にpsqlを実行してしまうと接続できずにエラーとなるため、疎通が確認できるまで待つようにしています。
ここではpsql -c \lを実行し、エラーが出力された場合はwhileをループするようにしています。

function healthcheck(){PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-c'\l'>$DEVNULL 2>&1 ||return 1
  return 0
}# startup postgres
docker run -it-d-p$PORT:$PORT--name$NAME-ePOSTGRES_PASSWORD=$PASSWORD postgres:latest >$DEVNULL# wait for container running upwhile true;do
  sleep 0.1 && healthcheck ||continue
  break
done

(テスト用)データベース、テーブルの作成、レコードのinsertとselect

テスト用PostgreSQLコンテナ内にDB、Tableを作成し、レコードをinsert, selectします(実際には既存のDBコンテナが立っているはずなので、この処理はコメントアウトされるでしょう)。

# (temporary) preparation postgresPGPASSWORD=$PASSWORD psql -h$HOST-U$USER-c"create database $DB"PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
  create table fruit (id serial PRIMARY KEY, name text, price integer);
  insert into fruit (name, price) values ('apple', 100), ('orange', 200), ('lemon', 300);
EOF

# select all records before updatesfor i in{1..3};do
PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
select name, price from fruit where id = ${i};
EOF
done

HTTPリクエストで取得したResponseを元にSQLを実行

curlでデータを取得します。ここではBitBankのPublic APIを利用しています。
取得したdataはヒアドキュメント内で参照され、psqlが実行されます。

# fetch data by HTTP Request# following response should be returned# {#   "success": 0,#   "data": {#     "code": 10000#   }# }data=$(curl -s$URL | jq '.data | .code')echo$data# update record with the dataPGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
  update fruit set price = ${data} where name = 'apple';
  update fruit set price = ${data} where name = 'orange';
EOF

レコードが更新されたことを確認

取得したdataによってレコードが更新されていることを確認します。

# select all records after updatesfor i in{1..3};do
PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
select name, price from fruit where id = ${i};
EOF
done

スクリプト全体

上記をまとめると、以下となります。
実際には下記のコードをアレンジしてご使用頂くかと思います。

#!/bin/bashreadonly NAME='test_postgres'readonly PASSWORD='password'readonly HOST='0.0.0.0'readonly PORT='5432'readonly USER='postgres'readonly DB='temp'readonly DEVNULL='/dev/null'readonly URL='https://public.bitbank.cc'function healthcheck(){PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-c'\l'>$DEVNULL 2>&1 ||return 1
  return 0
}function usage(){echo"please install docker, psql, jq, and curl"exit 1
}# check requirementsfor libName in docker psql jq curl;do
  which $libName>$DEVNULL|| usage
done# remove existing containerexist=$(docker ps -a | grep$NAME | wc-l | sed's/ //g')if[[$exist= 1 ]];then
  docker stop $NAME>$DEVNULL&& docker rm$NAME>$DEVNULLecho"existing container $NAME removed"fi# startup postgres
docker run -it-d-p$PORT:$PORT--name$NAME-ePOSTGRES_PASSWORD=$PASSWORD postgres:latest >$DEVNULL# wait for container running upwhile true;do
  sleep 0.1 && healthcheck ||continue
  break
done# (temporary) preparation postgresPGPASSWORD=$PASSWORD psql -h$HOST-U$USER-c"create database $DB"PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
  create table fruit (id serial PRIMARY KEY, name text, price integer);
  insert into fruit (name, price) values ('apple', 100), ('orange', 200), ('lemon', 300);
EOF

# select all records before updatesfor i in{1..3};do
PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
select name, price from fruit where id = ${i};
EOF
done# fetch data by HTTP Request# following response should be returned# {#   "success": 0,#   "data": {#     "code": 10000#   }# }data=$(curl -s$URL | jq '.data | .code')echo$data# update record with the dataPGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
  update fruit set price = ${data} where name = 'apple';
  update fruit set price = ${data} where name = 'orange';
EOF

# select all records after updatesfor i in{1..3};do
PGPASSWORD=$PASSWORD psql -h$HOST-U$USER-d$DB<<EOF
select name, price from fruit where id = ${i};
EOF
done

さいごに

久々にシェルスクリプトを書いたのですが、楽しいですね。
こんな書き方があるよ、といったコメント等あれば是非お願いいたします。


Viewing all articles
Browse latest Browse all 2722

Trending Articles