Skip to main content

Lambda

list functions

aws lambda list-functions
aws lambda get-function --function-name hello-world-python

You can download the zipfile of the source code with "jq -r '.Code.Location' result.json"

confirm CloudWatch Logs

aws logs describe-log-groups | jq .'logGroups[].logGroupName'
aws logs describe-log-streams --log-group-name /aws/lambda/hello-world-python
aws logs get-log-events --log-group-name /aws/lambda/hello-world-python --log-stream-name '2019/10/05/xxxxxxxx'

create function

aws lambda create-function --function-name hello-world-python \
--runtime python2.7 \
--handler lambda_function.lambda_handler \
--role arn:aws:iam::xxxxxxxx \
--zip-file fileb://../lambda_function.zip

modify function

aws lambda update-function-configuration --function-name hello-world-python --environment '{"Variables":{"key":"value"}}'
aws lambda update-function-code --function-name hello-world-python --zip-file fileb://../lambda_function.zip

invocation

aws lambda invoke --function-name hello-world-python --invocation-type DryRun --payload '{"message":"a b c 1 2 3"}' outfile.tmp
aws lambda invoke --function-name hello-world-python --payload '{"message":"a b c 1 2 3"}' outfile.tmp

delete function

aws lambda list-functions
aws lambda get-function --function-name hello-world-python
aws lambda delete-function --function-name hello-world-python

cloudformation sample template

    TestLambda:
      Type: AWS::Lambda::Function
      Properties:
        Code:
          S3Bucket: !Ref BucketName
          S3Key: "lambda_function.zip"
          S3ObjectVersion: !Ref S3ObjectVersion
        FunctionName: "TestFunction"
        Handler: "lambda_function.lambda_handler"
        MemorySize: 128
        Role: !GetAtt TestLambdaRole.Arn
        Runtime: "python2.7"
        Timeout: 3
        Tags:
          - "Key": "Name"
            "Value": "test"

CloudFormation

sample template of CloudFormation in yaml format

$ cat mystack.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  FirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
      - Key: Name
        Value: myfirststack

validate template file

$ aws cloudformation validate-template --template-body file://mystack.yml

create stack

$ aws cloudformation create-stack --stack-name mystack --template-body file://mystack.yml

confrim information of created stack

$ aws cloudformation list-stacks
$ aws cloudformation describe-stacks --stack-name mystack
$ aws cloudformation describe-stack-events --stack-name mystack --query 'StackEvents[?ResourceType==`AWS::CloudFormation::Stack`]'

$ aws cloudformation describe-stack-resources --stack-name mystack
$ aws cloudformation list-stack-resources --stack-name mystack

$ aws cloudformation get-template --stack-name mystack
$ aws cloudformation get-template --stack-name mystack | jq -r '.TemplateBody'
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  FirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
      - Key: Name
        Value: first-VPC

update template file and validate it

$ diff -u mystack.yml{,.bak}
--- mystack.yml 2019-09-16 11:23:04.368417527 +0900
+++ mystack.yml.bak     2019-09-16 10:51:35.053928361 +0900
@@ -1,12 +1,9 @@
 AWSTemplateFormatVersion: '2010-09-09'
-Parameters:
-  CidrBlock:
-    Type: String
 Resources:
   FirstVPC:
     Type: AWS::EC2::VPC
     Properties:
-      CidrBlock: !Ref CidrBlock
+      CidrBlock: 10.0.0.0/16
       Tags:
       - Key: Name
-        Value: mystack-VPC
+        Value: first-VPC

$ aws cloudformation validate-template --template-body file://mystack.yml

update the stack

$ aws cloudformation update-stack --stack-name mystack --template-body file://mystack.yml --parameters ParameterKey=CidrBlock,ParameterValue=10.0.0.0/17

confirm

delete the stack

$ aws cloudformation delete-stack --stack-name mystack

create stack with ansible

$ cat mystack.yml 
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  FirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.10.0.0/16
      Tags:
      - Key: Name
        Value: mystack

$ cat playbook.yml 
- hosts: 127.0.0.1
  connection: local
  gather_facts: False
  tasks:
    - name: create a cloudformation stack
      cloudformation:
        stack_name: "mystack"
        state: "present"
        region: "ap-northeast-1"
        disable_rollback: true
        template: "mystack.yml"

$ ansible-playbook --syntax-check playbook.yml 
$ ansible-playbook --list-tasks playbook.yml 
$ ansible-playbook --check playbook.yml
$ ansible-playbook playbook.yml

update stack with ansible

$ cat mystack.yml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  CidrBlock:
    Type: String
Resources:
  FirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref CidrBlock
      Tags:
      - Key: Name
        Value: mystack

$ cat playbook.yml 
- hosts: 127.0.0.1
  connection: local
  gather_facts: False
  tasks:
    - name: create a cloudformation stack
      cloudformation:
        stack_name: "mystack"
        state: "present"
        region: "ap-northeast-1"
        disable_rollback: true
        template: "mystack.yml"
        template_parameters:
          CidrBlock: "10.20.0.0/16"

$ ansible-playbook playbook.yml

variable from command line

$ cat mystack.yml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  CidrBlock:
    Type: String
Resources:
  FirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref CidrBlock
      Tags:
      - Key: Name
        Value: mystack

$ cat playbook.yml
- hosts: 127.0.0.1
  connection: local
  gather_facts: False
  tasks:
    - name: create a cloudformation stack
      cloudformation:
        stack_name: "mystack"
        state: "present"
        region: "ap-northeast-1"
        disable_rollback: true
        template: "mystack.yml"
        template_parameters:
          CidrBlock: "{{ CidrBlock }}"

$ ansible-playbook -e "CidrBlock=10.30.0.0/16" playbook.yml

delete stack with ansible

$ cat playbook.yml
- hosts: 127.0.0.1
  connection: local
  gather_facts: False
  tasks:
    - name: delete a cloudformation stack
      cloudformation:
        stack_name: "mystack"
        state: "absent"
        region: "ap-northeast-1"

$ ansible-playbook playbook.yml

json

json(JavaScript Object Notation)

  • object is unordered set of name/value pair.
  • array is ordered set of values
  • value can be number, string, boolean(true or false), null, object or array.

    { "number": 128, "string": "128", "boolean": true, "null": null, "object": { "key0": "value0" }, "array": [ 128, "128", true, null, { "key1": "value1" } ] }

jq

jq is command line json processor. How to install jq in debian.

apt-get install jq

Here we use result of below command as a sample json file. Of cource I know awscli has convinience options like filter and query.

aws ec2 describe-images \
--filters '[{"Name":"owner-id","Values":["136693071363"]},{"Name":"architecture","Values":["x86_64"]}]' > ami.json

内容全てを整形して出力

$ jq '.' ami.json

Images の子要素(配列)を全て出力

$ jq '.Images[]' amis.json

Images の子要素のうち Description が Test のものの内容を出力

$ jq '.Images[] | select(.Description == "Test")' ami.json

Not condition

$ jq '.Images[] | select(.Description == "Test" | not)' ami.json

Startswith

$ jq '.Images[] | select(.Description | startswith("Debian 10"))' ami.json

contains

$ jq '.Images[] | select(.Description | contains("202005"))' ami.json

Images の子要素のうち Description が Test のもののNameの値を出力

$ jq '.Images[] | select(.Description == "Test") | .Name' ami.json

Images の子要素のうち Description が Test のものの内容を整形して出力

$ jq '.Images[] | select(.Description == "Test") | {"MyName":.Name, "MyDate":.CreationDate}' ami.json

jqのコマンドをファイルから読み込むことができる。

$ cat ami.jq
.Images[] |
select(.Description == "Test") |
{
  "MyName":.Name,
  "MyDate":.CreationDate
}

$ jq -f ami.jq ami.json

シェバンを書けば、sed や awk のようにスクリプトとして実行することができる。

$ cat ami.jq
#! /usr/bin/jq -f
.Images[] |
select(.Description == "Test") |
{
  "MyName":.Name,
  "MyDate":.CreationDate
}

$ chmod +x ami.jq

$ ./ami.jq ami.json

adding value of add.json to ResourceRecordSet part of orig.json

$ jq . orig.json
{
  "Comment": "delete after certbot validation",
  "Changes": [
    {
      "Action": "DELETE",
      "ResourceRecordSet": {
        "Name": "_acme-challenge.'${CERTBOT_DOMAIN}'.",
        "Type": "TXT"
      }
    }
  ]
}
$ jq . add.json 
{
  "ResourceRecords": [
    {
      "Value": "\"abcd1234\""
    }
  ],
  "TTL": 1800
}
$ jq '.Changes[0].ResourceRecordSet |= .+ '$(jq -c . add.json)'' orig.json
{
  "Comment": "delete after certbot validation",
  "Changes": [
    {
      "Action": "DELETE",
      "ResourceRecordSet": {
        "Name": "_acme-challenge.'${CERTBOT_DOMAIN}'.",
        "Type": "TXT",
        "ResourceRecords": [
          {
            "Value": "\"abcd1234\""
          }
        ],
        "TTL": 1800
      }
    }
  ]
}

eBook reader

漫画は読まない。

電子書籍の利点は、物理的な重さや容積を考慮する必要がないこと。何百ページの本でも好きなだけいつでもどこにでも持ち運ぶことができる。家に保管するスペースも必要ない。

よく言われる電子書籍の欠点として、万が一サービスが終了したら、買った本が読めなくなる、というのがある。 (物理的に紙の本を買ったとしても、汚したり紛失したり、最悪の場合焼失したりする可能性はあり、未来永劫手元に残ることが保証されるわけではない。) 未来永劫手元に残らなくてもよい本なら、サービスを利用する価値があるのではないかと思う。資格関連本など、墓場まで持っていかなくてもよいタイプの本は、意外と多いはず。 中期から短期的にサービスを受けることができる有料サービスで、優れたコンテンツを手軽に持ち運んで読むことができると捉えれば、電子書籍は合理的なのではないだろうか。

電子書籍では書き込みができないという短所もあるが、本当に必要なところだけノートに書き写すなりすればよいのではないかと思う。本に書き込んだことを繰り返し参照するという運用が、本当に効率的なのであれば、紙の本を使えばいいし、そうでないなら電子書籍で充分ではないかと思う。

電子書籍には紙の手触りがない、紙の本なら直感的にどのあたりに何が書いてあったか覚える、という意見がある。 例えばkindle の場合、好きなページに好きなだけしおりを設定することができる。電子書籍でも、自分で設定したしおりを頼りにすれば、好きなところに比較的簡単にたどり着けるのではないかと思う。

紙の本を全否定するのではないが、雑誌を切り抜いてスクラップしたりハードカバーの本を手元におきたいなど、紙の本がどうしても必要だという事情がないのなら、電子書籍を活用しないのはもったいない。 紙の本だと人に貸すこともできるし、不要になれば売り払うこともできる。

お菓子を食べながら読んでも、コーヒーをこぼしても、電子書籍コンテンツ自体は汚れることはない。 電子書籍端末は、気に入る端末が限られるので、大切に使わないと代わりになるものに出会えなくなる可能性もある。(買いたくなるような7インチタブレットがなかなか出てこない)

電子端末の持ち込みが制限される職場には持ち込むことができない可能性がある。

自分の場合、荷物を増やしたくないので、雑誌も書籍も物理的な本はあまり買わず、短期間で読みきるタイプの本の場合は図書館を積極的に利用するようにしている。

kindle

最大手のサービスなら、そう簡単にサービスが終わることはないと考え、自分はAmazon を利用している。 (極東の島国の企業に買収されるようなサービスでは安心して利用できない)

kindleは、専用端末は必ずしも必要ではなく、Androidやiosの普通に売られてるスマホやタブレットにアプリを入れて使うことができる。また、一つのアカウントで複数の端末を使うことができる。

Adobe Acrobat Reader

オープンソースソフトウェアに限らず様々な製品のドキュメントがPDF 形式で配布されている。 タブレット端末に入れて持ち運ぶと、手軽にどこでも快適に読むことができ、とても重宝する。

FBReaderPDF plugin

epubをはじめ、様々な形式に対応したドキュメントリーダー。 2つのPDF ファイルを切り替えながら読むためにAdobe リーダーとあわせて使っている。

青空プロバイダ縦書きビューア

自分は青空文庫の本を読むのにこれらを使っている。

かつて紙の文庫本を買って読んだ古典が(全てではないが)無償で読めるのは、感慨深い。

Perfect Viewer

様々な形式に対応したドキュメントリーダー。 電子書籍だけでなく、画像ファイルの閲覧にも対応している。

weightloss

減量=摂取カロリーと消費カロリーの収支をマイナスにする努力。

メタボには該当しないがBMI的に標準体重の上限近いので、減量に取り組んでいる。

無理をせず1週間で 300g くらいずつ減らしていき、数十週かけて標準体重の中ほどを目指している。(1日あたりカロリー収支を、300kcal 消費超過とする。)

急に減量すると防御が働くそうなので、あせらず少しずつ。 月に5%にとどめたほうがいいらしい(一週間あたり1%程度)。

カロリー消費は食事誘導性熱産生、生活活動、基礎代謝 (= 1 : 2 : 7)だけ。できることをこつこつ積み重ねるしかない。

摂取カロリーを減らす

食欲のコントロール。満腹感を得ることを目的としない。 軽い空腹感があったほうが集中力が高まる。

  • 食べる量を単純に減らす(半ライスにする。大盛りにしない。追加しない。時間をかけて食べる。)
  • 食事=次の食事までに使う分のカロリーを摂取すること(食べるのは必要な量だけにとどめる)
  • 高カロリーを摂らない。or 低カロリーに入れ替え。 食べるなら意識して食べる。 (コーラ、ポカリ、栄養ドリンク。菓子パン。食後のお菓子。おやつ。マヨネーズ、ドレッシング、バター、砂糖、揚げ物。) お菓子を食べるなら一口ゼリー。

消費カロリーを増やす

  • いつもより[徒歩・自転車・階段]。

カロリーを消費しやすく

  • 食事を抜かず三食食べる (朝しっかり、昼減らす、夜あっさり)
  • 体温を上げる (カプサイシン)
  • 筋肉を増やす (ドローイン → ストレッチ → 筋トレ) 体脂肪が減り引き締まる。

脂肪消費を進める

  • 筋肉をつけて有酸素運動
  • 運動前にプーアル茶(脂肪分解をすすめる効果があるらしい)

脂肪吸収を抑える

  • 食事の際は烏龍茶(脂質吸収を抑える効果があるらしい)
  • 食後血糖値上昇を抑える(食後に運動する。デザートのお菓子をやめる)
  • 炭水化物を減らす

生活習慣

  • 就寝中のカロリー消費(7~7.5h睡眠)

目標設定・進捗管理

  • 体重と体脂肪率を1日2回記録する(起床後と就寝前など)。
  • 計画・実行・反省・改善を辛抱強く継続する。 休むとリカバリが難しいので休まない。 習慣化する。減量した状態をキープする。
  • なぜ減量したいのか。減量して得られるものを思い描く。 なりたい自分を目指して生活習慣を改善する。

停滞期

体重が5%くらい減ると防御が働いて、数週間体重が減らなくなる。この間も辛抱してがんばる。

心が折れそうなときは 「怠惰な豚でいたくない。でぶは自己管理できないことの表れ。みっともない。」と言い聞かせてがんばる。

何事も始めるのに遅すぎるということはない。変化を恐れず、常に自分を変えて成長する。

stop smoking

数年前に禁煙成功し、それ以来完全にやめることができた。 その時に考えたこと、やったことなど。

禁煙 = 一度決めたことを継続する心の強さこそが力 禁煙できれば何でもできる。禁煙すらできなければ何もできない。

意志があれば禁煙外来に行かなくても、禁煙ガム・禁煙パッチがなくても禁煙できる。意思がなければ、何をやってもやめられるわけがない。

考え方を変える

煙草を吸い続ける価値はない、煙草を吸わないのが合理的であると覚悟する。

煙草による不都合。

  • くさいので、嫌がられる。迷惑になる。迷惑をかけていることに無自覚。
  • 味や臭いに鈍感になる。
  • 食事・休憩できるところが限られる。
  • 煙草代。
  • 将来の医療費がかかる。他人への健康被害。
  • 吸ってる時間が無駄。余命が短い。
  • 火の不始末の心配。煙草やライターの在庫の心配。

禁煙で得られるもの。

  • くさくないので、嫌がられない。迷惑にならない。
  • 味や臭いが判るようになる。
  • どこでも飲食できる。(むしろ喫煙席の近くは臭いと感じるようになる)
  • 煙草代がかからない。
  • 将来の医療費がかかる可能性が下がる。
  • 無駄な時間が減る。余命が短くなくなる。
  • 心配事が減る。
  • 自信。

煙草を吸う人がかっこいいというのは幻想にすぎない。 自分では気づかないだけで、世間の人は喫煙者をこう見てる。

  • 煙で他人に迷惑をかけておきながら自分がかっこいいと勘違いしている痛い人。
  • 煙で他人に迷惑をかけても気にしないタイプの人。
  • 自分を律することができないタイプの人。
  • ゴミをポイ捨てして灰をちらかす人と同族。ところ構わず歩き煙草する人と同族
  • 臭い人。(匂いで頭痛を起こす人がいる)

迷惑行為を他の誰かがやっているから自分もやっていいというのは、言い訳にもならない。

客観視と減煙

失敗してもあきらめない。最初は間引きから入ってもいい。

  • 何故吸っているのか、どんなときに吸っているのかを自覚する。 惰性で吸わない。本当に吸いたい気持ちがあるのか自問して、吸いたい気持ちがあるときにだけ吸う。
  • 何気なく吸わない。付き合いで吸わない。吸いたい気持ちが少ないのなら吸わない。
  • 煙草を吸うのが習慣となっている場合、それをやめてみる 食事前後だから吸う。お風呂上りだから吸う、などというのはやめる。
  • 吸いたくなるポイントで吸わないようにできるか試してみる 起床後。朝食の前後。午前中。昼食前後。午後。夕食前後。お風呂前後。就寝まで。
  • 連続で吸わない。 一度に吸うのは1本だけ。煙草の間隔を数時間開ける
  • イライラしたから吸いたい? 緊張したから吸いたい? 煙草は甘えや逃避でしかない。感情を制御できるようにする。 (煙草を吸わない人は、煙草を吸わなくてもイライラや緊張と付き合ってる)

実践

  • 禁煙を初めて最初の2週間は心が折れそうになっても、強い決意で吸わない。
  • 1か月経って自信がついたとしても、ここまでの辛い思いを無駄にしないように吸わない。
  • 数か月経ってふと吸いたくなることがあっても、ここまで煙草無しで生活することができているので吸わない。
  • 1年経つと疾病可能性が下がってきているので、せっかくなので吸わない。

吸いたいイライラに負けない。周囲の人に当たらない。

吸いたくなるのは数分間だけであり、それを我慢できればしばらくは大丈夫。 最初は吸いたくなる欲求が強いが、数か月かけてだんだん下がってくる。 吸いたくなる間隔もだんだん開いてくる。 その様子を客観的に観察してモチベーションとする。記録する。

吸いたくなる数分間を我慢できなくなりそうな時 何か飲み物を飲む。タブレット菓子を食べる。席を立つ。気分転換をする。ストレッチ。瞑想。深呼吸。

何度も禁煙に失敗してもあきらめない。 甘えを捨てて、自分には厳しく。周囲の人には感謝。

perl

リストの内容だけ繰り返す

#! /usr/bin/perl

@list = (' item1 ', ' item2 ');

foreach $val (@list) {
  s/ //g;
  print "$val\n";
}

リストの内容だけ繰り返す(特殊変数を使用)

#! /usr/bin/perl

@list = (' item1 ', ' item2 ');

foreach (@list) {
  s/ //g;
  print "$_\n";
}

#! /usr/bin/perl

@list = ('item1', 'item2');
myfunction(@list);

sub myfunction {
  foreach ( @_ ) {
    print "$_\n";
  }
}

標準入力から入ったものをそのまま出力1

#! /usr/bin/perl

foreach (<>) {
  print $_;
}

while

while (<>) {
  s/[\r\n]//g;                  # 改行コードを除去。
  next if ( $_ eq "" );         # 空行ならスキップ
  next if ( /^#/ );             # コメント行はスキップ
  my ($var1, $var2) = split( /\s+/, $_);
  :
}

ファイルハンドラ

#!/usr/bin/perl

$filename = "filename.txt";

open(my $fh, "<", $filename) 
  or die "cannot open < ".$filename.": $!";

while ( <$fh> ) {
  s/[\r\n]//g;                  # 改行コードを除去。
  next if ( $_ eq "" );         # 空行ならスキップ
  next if ( /^\s*#/ );          # コメント行ならスキップ

  :
  :

 }

close($fh)
  or warn "close failed: $!";;

引数の利用

#! /usr/bin/perl

my $count = @ARGV;
if ( $count == 0 ) {
  print "引数がないっす";
}

foreach (@ARGV) {
  print "$_\n";
}

オプションと引数

#! /usr/bin/perl

use Getopt::Std;

my $flg=0;
getopts("f:tdh", \%opts);

if ($opts{'f'}) {
  $flg = $flg + 1;
  print $opts{f};
  print "\n";
}
if ($opts{'t'}) {
  $flg = $flg + 2;
}
if ($opts{'d'}) {
  $flg = $flg + 4;
}
usage() if ($opts{'h'}) ;

print "$flg\n";

my $count = @ARGV;
print "$count\n";
foreach (@ARGV) {
  print "$_\n";
}

sub usage {
  print "help message...\n";
}

http

#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;

$url='http://xxx.xxx.xxx.xxx/xxx.html';

my $proxy = new LWP::UserAgent;
my $req = HTTP::Request->new('GET' => $URL);
my $res = $proxy->request($req);

$source = $res->content;
$source =~ s/<.*?>//g;

日付について1

#! /usr/bin/perl

my @week = qw(Sun Mon Tue Wed Thu Fri Sat);
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
#my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time());

$year = $year + 1900;
$mon  = $mon + 1;
$yday = $yday + 1;

print "$year-$mon-$mday $hour:$min:$sec\n";
print "$year-D$yday $week[$wday]\n";
if ( $isdst ) { print "summer time\n"; }

日付について2

#! /usr/bin/perl

use POSIX;

my $isleap = 0;
my @mdays  = (31,28,31,30,31,30,31,31,30,31,30,31);
my $ydays;
my $message;

my ( $year, $month, $day, $dow, $downum, $doy, $woy ) = split( /\,/, strftime( "%Y,%m,%d,%A,%w,%j,%W", localtime() ) );

if ( ( $year % 4 ) == 0 ) {
  if ( ( ($year % 100) != 0 ) || ( ($year % 400) == 0 ) ) {
    $isleap = 1;
    $mdays[1] = 29;
  }
}

$ydays  += $_ for @mdays;
#$month  += 0;
#$day    += 0;
#$doy    += 0;
#$woy    += 0;

$message = "今日は $year年$month月$day日、第$woy週の$dowです。\n";
if ( $isleap ) { $message = $message."閏年なので"; }
$message = $message."年間日数 $ydays日あるうちの $doy日目です。";

print $message;
exit;

日付について3

#! /usr/bin/perl

use Time::Local;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time()+3600);

my $time = timelocal( $sec, $min, $hour, $mday, $mon, $year );

my $string =  localtime($time);

print $string;
exit;

sql for sqlite

SQliteで使える言語 について

SQliteは、型を指定しなくても CREATE TABLE できるのが特徴。 型指定するなら、integer, real, text, blob型を使える。

CREATE TABLE IF NOT EXISTS mytable (
id INT,
description TEXT,
score REAL
);

トランザクション

BEGIN TRANSACTION;
:
COMMIT or ROLLBACK;

クエリ計画の表示

EXPLAIN QUERY PLAN ~;

パフォーマンス対策

REINDEX [target];
VACUUM;
ANALYZE;

日付・時刻関数

日付・時刻の型は無いが、関数を使って扱うことができる。

現在日時の例(デフォルトでUTCとして扱われる)

SELECT current_timestamp, date('now'), time();

文字列で特定日時を指定する。

SELECT datetime('1970-01-01 00:00:00')||' はUTCの時刻';

修飾子にlocaltimeを指定すると、ローカルのタイムゾーンに変換。(JSTの場合、9時間後)

SELECT datetime('1970-01-01 00:00:00+09:00')||' はUTCなので、JSTは '||datetime('1970-01-01 00:00:00+09:00', 'localtime');
SELECT datetime('now')||' はUTCなので、JSTは '|| datetime('now', 'localtime')x;

修飾子にutcを指定すると、対象の日付がローカルのタイムゾーンのものとして、utcに変換。(JSTの場合、9時間前)

SELECT datetime('now')||' がJSTだとしたら、UTCは '||datetime('now', 'utc');

その他、修飾子を使うことができる。

SELECT datetime('now', '+1years', '+1months', '+1days', '+1hours', '+1minutes', '+1seconds');
SELECT '今年の第1月曜日は '||date(datetime('now', 'start of year'), 'weekday 1');

条件式として使うことができる

SELECT * FROM mytable WHERE date BETWEEN datetime('now', '-3hours') AND datetime('now');
SELECT * FROM mytable WHERE date(date) = date('now');

strftime書式を使うことができる

SELECT strftime('%s', '1970-02-01 00:00:00', '-1 minutes');
SELECT datetime(strftime('%s', '1970-01-01 00:00:00'), 'unixepoch');

集約関数

ccount, avg, min, maxなどの集約関数が使える。

SELECT col1 AS c1, aggregate(col2) AS c2
FROM mytable
WHERE condition 集計する対象を絞り込む。
GROUP BY c1
HAVING c2 <> 0; 集計結果から、出力する対象を絞り込む

コア関数

引数の中で、最初に現れたNULLでない値を返す (この例では「全部null」)

SELECT coalesce(null, null+'any', null+1, null*1, null/1, 1/0, '全部null');

制約について

CHECK制約の列制約の例

CREATE TABLE IF NOT EXISTS point (
  pointname TEXT CHECK(length(pointname) <= 8),
  latitude  REAL NOT NULL CHECK(latitude  BETWEEN  -90.0 AND  90.0),
  longitude REAL NOT NULL CHECK(longitude BETWEEN -180.0 AND 180.0),
  CONSTRAINT point_primary PRIMARY KEY (pointname)
);

表制約の例(制約名は省略可能)

DROP TABLE IF EXISTS point;
CREATE TABLE IF NOT EXISTS point (
  pointname TEXT PRIMARY KEY,
  latitude  REAL NOT NULL,
  longitude REAL NOT NULL,
  CHECK(length(pointname) <= 8),
  CHECK(latitude  BETWEEN  -90.0 AND  90.0),
  CHECK(longitude BETWEEN -180.0 AND 180.0)
);

外部キーの例

列制約

CREATE TABLE IF NOT EXISTS route (
  routename TEXT CHECK(length(routename) <= 8),
  seq       INT  NOT NULL,
  pointname TEXT NOT NULL REFERENCES point(pointname),
  PRIMARY KEY (routename, seq)
);

表制約

DROP TABLE IF EXISTS route;
CREATE TABLE IF NOT EXISTS route (
  routename TEXT CHECK(length(routename) <= 8),
  seq       INT  NOT NULL,
  pointname TEXT NOT NULL,
  PRIMARY KEY(routename, seq),
  FOREIGN KEY(pointname) REFERENCES point(pointname)
);

SQlite 3.6.19から外部キーの機能が導入されたが、デフォルトでは機能しない。 (外部キーのDDLはエラーにならない。外部キー制約で拒否されるはずの値が拒否されない。) 制約を有効にするためには(データベースを開くたびに)設定が必要。

PRAGMA foreign_keys;
0→オフ
1→オン
PRAGMA foreign_keys = [ON|OFF];

(補足: sqlite_version()関数でバージョンを確認できる。)

デフォルト値

DROP TABLE IF EXISTS track;
CREATE TABLE IF NOT EXISTS track (
  trackname TEXT,
  timestamp TEXT DEFAULT CURRENT_TIMESTAMP,
  latitude  REAL NOT NULL,
  longitude REAL NOT NULL,
  PRIMARY KEY(trackname, timestamp),
  CHECK(length(trackname) <= 8),
  CHECK(datetime(timestamp) IS NOT NULL
    AND datetime(timestamp) >= datetime('1970-01-01 00:00:00')),
  CHECK(latitude  BETWEEN  -90.0 AND  90.0),
  CHECK(longitude BETWEEN -180.0 AND 180.0)
);

結合

内部結合

SELECT r.routename, r.seq, p.latitude, p.longitude FROM point AS p, route AS r
WHERE r.pointname = p.pointname;

SELECT r.routename, r.seq, p.latitude, p.longitude FROM point AS p
JOIN route AS r
WHERE r.pointname = p.pointname;

SELECT r.routename, r.seq, p.latitude, p.longitude FROM point AS p
JOIN route AS r
ON r.pointname = p.pointname;

SELECT r.routename, r.seq, p.latitude, p.longitude FROM point AS p
JOIN route AS r
USING (pointname);

外部結合 (LEFT OUTER JOINは実装されているが、RIGHT と FULL OUTER JOINは実装されていない。)

SELECT r.routename, r.seq, p.latitude, p.longitude FROM point AS p
LEFT OUTER JOIN route AS r
ON r.pointname = p.pointname;

自然結合

SELECT r.routename, r.seq, p.latitude, p.longitude FROM point AS p
NATURAL JOIN route AS r;

その他

CASE文

SELECT
  CASE strftime('%M','now') % 3
    WHEN 0 THEN 'is 0'
    WHEN 1 THEN 'is 1'
    ELSE 'is 2'
  END,
  CASE
    WHEN strftime('%M','now') % 2 = 0 THEN 'even'
    ELSE 'odd'
  END
;

kernel parameter

ipv4 のルーティング設定の例

設定値確認

cat /proc/sys/net/ipv4/ip_forward
or
sysctl [-n] net.ipv4.conf.all.forwarding

全てのパラメータを表示
sysctl -a

一時設定

echo 1 > /proc/sys/net/ipv4/ip_forward
or
sysctl -w net.ipv4.conf.all.forwarding=1

恒久設定

cat << END >> /etc/sysctl.conf
net.ipv4.conf.all.forwarding = 1
END
sysctl -p