OmniAICreator/Qiita-1.07M huggingface dataset:
Azure Reposで管理しているファイルをAPIで取得する

### 背景

GitHubのRaw URLみたいな感じが一番理想でした。

以前はGitBucketを使っており、こちらはプライベートリポジトリで認証が必要でもGitHub互換APIのおかげで取れました。

そしてAzure Reposに移ることになりそうだったので、調べてみました。

### Rest APIを使う

Rest APIでファイルの内容の取得もできます

See: https://docs.microsoft.com/ja-jp/rest/api/azure/devops/git/items/get?view=azure-devops-rest-4.1

```
# 最小限スタイル
https://dev.azure.com/組織名/_apis/git/repositories/リポジトリID/items?path=ファイルパス&api-version=4.1

# プロジェクト名を指定すると、リポジトリはIDではなくリポジトリ名で取れます（ドキュメントには書いてない模様）
https://dev.azure.com/組織名/プロジェクト名/_apis/git/repositories/リポジトリ名/items?path=ファイルパス&api-version=4.1
```

ちなみに、ブランチ名がない場合はデフォルトブランチになります。また、ファイルパスは`/`始まりで、たとえばよく一番上にある`README.md`なら、`/README.md`のようになります。

（`download=true`も付けたほうがよさそうだけど、有無の違いがよくわからなかった…Acceptヘッダーで動きが変わるかも？）

### ブランチ名かコミットIDを指定をしたい

`versionDescriptor.version=ブランチ名`をクエリに足します。タグ名やコミットIDでも良いです。

```
https://dev.azure.com/組織名/プロジェクト名/_apis/git/repositories/リポジトリ名/items?path=ファイルパス&versionDescriptor.version=ブランチ名&api-version=4.1
```

### そもそもrepositoryId（リポジトリID）はどこで見れるのか

リポジトリの一覧を取るRest APIがあるので、これで見れます。

See: https://docs.microsoft.com/ja-jp/rest/api/azure/devops/git/repositories/list?view=azure-devops-rest-4.1

```
https://dev.azure.com/組織名/プロジェクト名/_apis/git/repositories?api-version=4.1
```

JSONでリポジトリの数だけリストが返ってくるので、いい感じに読み解くと得られます。


一応、画面から見る方法があります。（今後も見れるかどうかは不明）
プロジェクトを開き、Project Setting → Code > Repositories → リポジトリ名の順に選択し、アドレスバーのURLを見る。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52527/bf6f54b5-53c9-2189-a2e0-d3e5b9400f06.png)

私はRest APIの存在を知った後にもかかわらず、愚かにも画面上から探して見つけました。


### Privateリポジトリの場合は？

Privateリポジトリに対する操作について、ブラウザ上の場合はCookieが覚えてくれていると勝手に処理されるので気にせずとも使えます。しかし、curl等で使いたい場合は、認証情報を渡す必要があります。でも、個人の認証情報は気が引けますよね。

そこで、Personal Access Token(PAT)を発行することで、それを自分の認証情報の替わりとして使えます。
See: https://docs.microsoft.com/ja-jp/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=tfs-2017


設定方法は上記を見ていただくとして、権限を選択について。
Azure Reposなら「Code」の「Read」権限だけつければGitリポジトリの読み取りができます。許可する権限は必要最小限で行きましょう。

- **※PATの有効期間は最大で1年先までしか指定出来ないので注意が必要です**
    - 7日前には通知が来るようです
    - 個人に紐づきます
    - 有効期間の更新は一応できそうです

個人につくのと、期限の縛りが辛いので、プロジェクトorリポジトリ単位で作れないか、サービスプリンシパルが使えないか、とか他の方法がないか調べていますが、今のところなさそうです。「チーム用のユーザ」を作るしかないのか…？



それはともかく、使い方はこんな感じです。Basic認証の要領でいけます。

git cloneする例

```
git clone https://トークン名:トークン値@dev.azure.com/組織名/プロジェクト名/_git/Gitリポジトリ名
```

Rest APIで`/README.md`コンテンツを得る例

```
curl https://トークン名:トークン値@dev.azure.com/組織名/_apis/git/repositories/リポジトリID/items?path=/README.md&api-version=4.1
```



### 終わり

ファイアウォールの都合でPull型のデプロイを採用しているため、こういうことがしたくなるんですが、あまり聞きませんね・・・デプロイの仕方については全然知見がない。

あと、PATの有効期間については、漏洩のリスクとかを考えての設定だと思うのですが、更新忘れで使えなくなるリスクのほうが現実的にはありそうなので、無期限も選べるようにして欲しい・・・。それに、サービスプリンシパルなら事実上の無期限を選べますよね。この差はなんだ？納得いかんぞ！
[iOS] 使用しているライブラリの情報を色々得るためのメモ

## 概要

今の案件で、どうやら他人が作ったライブラリの中の関数でメモリリークが発生しているようで、色々解析するのに調べたものをつらつらとメモ。

調べる中でメモりたいものをメインにメモっているのでとりとめない＋随時更新です。


## アーカイブファイル「.a」の中身を確認する

アーカイブファイル（`.a`ファイル）などの中身を確認するには、`lipo`コマンドを使うことで行えます。

### アーキテクチャを確認する

```console
$ lipo -info hoge.a
Architectures in the fat file: hoge.a are: armv7 i386 x86_64 arm64
```

上のような結果が得られます。
当然、調べるアーカイブファイルによって多少異なります。
上の例では複数アーキテクチャが含まれていることが分かりますね。
（`armv7 i386 x86_64 arm64`の4つ）


### 特定アーキテクチャのもののみを取り出す

また、その中から特定のアーキテクチャのものだけを取り出す場合は以下にようにコマンドを実行します。

```console
$ lipo -thin arm64 hoge.a -output hoge_arm64
```

### 対象のオブジェクトファイルを探す

次に、`ar`コマンドを使うことで対象アーカイブファイルの中身を確認することが出来ます。

```console
$ ar -t hoge_arm64
__.SYMDEF
QrEncode.o
Unity3DInterface.o
InputSource.o
Types.o
... # 以下略
```

実行すると上記のように、アーカイブファイル内にまとめられているオブジェクトファイルの一覧を表示することができます。

目的のオブジェクトファイルを見つけたら、以下のようにすることで対象オブジェクトファイルを取り出すことができます。

```console
$ ar -x hoge_arm64 InputSource.o
```

その他、`ar`コマンドを使うことでアーカイブにオブジェクトファイルを追加したり、など様々な処理が行なえます。
詳細についてはこちら→ 「[ar - コマンド (プログラム) の説明 - Linux コマンド集 一覧表](https://kazmax.zpp.jp/cmd/a/ar.1.html)」


## オブジェクトファイルの中身を確認する（ディスアセンブル）

`objdump`コマンドを使うことで、オブジェクトファイルをディスアセンブル（`disassemble`）することができます。

```console
$ objdump -d InputSorce.o
```

実行すると標準出力にダーっと内容が出力されます。
ファイルに書き出すことで見やすくなるので、実際にはファイルに書き出すのがいいと思います。

```console
$ objdump -d InputSorce.o > hoge.s
```

アセンブラについては以前に、（触り程度ですが）記事を書いたので興味があったら読んでみてください。

- [[アセンブラ] ARMの仕様を見てみる](https://qiita.com/edo_m18/items/a7c747c5bed600dca977)
- [アセンブラに手を出してみる](https://qiita.com/edo_m18/items/83c63cd69f119d0b9831)
Goでの素数判定と時間計測

## はじめに
Go初心者なので生温かい目で読んで頂ければと思います。
Goの練習として、素数判定のアルゴリズムを書き、時間計測する。
アルゴリズムは２通り。時間計測はtimeパッケージを使う。
1. 整数xに対して、２からx-1まで順に、割り切れるかどうか試して判定する。
2. 整数xに対して、偶数は先に判定し、３から√xまで順に２づつ増やしながら、割り切れるかどうか試して判定する。

## 環境
Go 1.11.2

## ソース
```prime.go
package main

import (
	"fmt"
	"math"
	"time"
)

func isPrime(x int) bool {
	if x == 1 {
		return false
	}
	if x == 2 {
		return true
	}

	b := true
	for i := 2; i < x; i++ {
		if x%i == 0 {
			b = false
			break
		}
	}
	return b
}

func isPrime2(x int) bool {
	if x == 1 {
		return false
	}
	if x == 2 {
		return true
	}
	if x%2 == 0 {
		return false
	}

	b := true
	rootx := int(math.Sqrt(float64(x)))
	i := 3
	for i <= rootx {
		if x%i == 0 {
			b = false
			break
		}
		i += 2
	}
	return b
}

func main() {
	var i int
	// 標準入力を代入
	fmt.Scan(&i)

	start := time.Now()
	b := isPrime(i)
	end := time.Now()
	fmt.Println(b)
	fmt.Printf("%f秒\n", (end.Sub(start)).Seconds())

	start = time.Now()
	b = isPrime2(i)
	end = time.Now()
	fmt.Println(b)
	fmt.Printf("%f秒\n", (end.Sub(start)).Seconds())
}
```

## 実行

標準入力から97, 997, 9973で試します。

```
$ go run prime.go
97
true
0.000004秒
true
0.000000秒
$ go run prime.go
997
true
0.000030秒
true
0.000001秒
$ go run prime.go
9973
true
0.000380秒
true
0.000002秒
```
大きい数ほど、isPrime2(2の方法)が速いのが明らかになっています。:clap:

これで終わりとなりますが、またの機会に、別の言語（Pythonとか）との速度比較などしてみたいですね。

## 参考
[素数表](http://allthingsuniverse.com/jp/prime/10000.html)
[素数判定いろいろ](https://qiita.com/srtk86/items/874639e361917e5016d4)
ModuleNotFoundError: No module named '_bz2'


gensimをimportしたらエラーが出てしまったので。

```
ModuleNotFoundError: No module named '_bz2'
```

### 環境
Ubuntu 16.04.5 LTS
Python 3.6.6

### 対応
```bash
sudo apt-get install libbz2-dev

pyenv uninstall 3.6.6
pyenv install 3.6.6

# pip install gensim
```

※ Pythonの再インストールが必要。
あと、pipでインストールしてたものも。


### 参考
https://qiita.com/kasajei/items/5e22161b62f4b84787bc
macの端末上でgitを使えるようになるまで

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">何をするにもgitが必要なので今週はgitを極めようと思います</p>&mdash; ゆうすけ (@chelsea08ym) <a href="https://twitter.com/chelsea08ym/status/1069236812781019136?ref_src=twsrc%5Etfw">2018年12月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

というわけでgitをmacの端末上に導入するところまでできたので、備忘録として残しておきます。
参考元：[今日からはじめるGitHub](https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000)

Qiita史上一番分かりやすく書いたつもりなので、書いてある通りやればみんな使えるようになるかと思います。

これを見てる人は何かしらの理由でgitを使いたいと考えてる人だと思ってるので、〜に使えるだとかの使い道の説明はカットします。


##GitHubアカウントの作成
[こちら](https://github.com/)からGitHubへいき、アカウントを作成してください。

無料と有料のプランがありますが、お好きな方を選んでください。
最後にe-mailでの承認をしたらアカウントが無事に取得できると思います。


##ターミナルの起動

```terminal
git --version
git version 2.17.2 (Apple Git-113)
```

if(gitが入ってない)
　[こちら](https://qiita.com/furusin_oriver/items/974a7b7fb8c56ad88d6e)を参照。;

##ユーザ名とEメールの設定

```terminal
git config --global user.name "ユーザ名"
git config --global user.email "your_email@example.com"
```

##SSHキーの取得
リモート操作するのに必要なのでSSHキーを取得します。

```terminal
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
```

-t:タイプ指定
-b:ビット数指定
-C:コメント

ssh-keygenについて詳しく知りたければ[こちら](https://euske.github.io/openssh-jman/ssh-keygen.html)を参照。

キー生成後は以下のようになってることが確認できると思います。

```terminal
ls ~/.ssh/
// ↓結果
config		id_rsa		id_rsa.pub	known_hosts
```

.pubとなっているのがパブリックキーのことです。

##パーミッションの設定

```terminal
chmod 600 ~/.ssh/id_rsa
```
chmodはアクセス権限の変更をするコマンドで今回は所有者(User)に読み書きの権限を与えるので600としました。
なぜ600なんだ？と思った人は[こちら](https://qiita.com/shisama/items/5f4c4fa768642aad9e06)を参照してください。

##configファイルの設定

```terminal
vim ~/.ssh/config
```

vimを開いたら以下をペーストしてください。

```vim
Host github
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa
```

if(vimの使い方がわからない){
  i（インサート）モードにし、ペースト
  escでコマンドモードに戻る
  ZZで上書き保存して終了
}

vimコマンドについて詳しく知りたければ[こちら](https://qiita.com/hide/items/5bfe5b322872c61a6896)を参照。

##公開キーの登録
最初にGitHubのアカウントを作成したと思うので、Github画面の右上からSettingsへいきます。
<img width="217" alt="スクリーンショット 2018-12-07 11.40.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/316760/96813b78-5e4a-a0ec-bfc9-9fcfcc344bd8.png">

SettingsまでいったらSSH and GPG keys からNew SSH keyを選びます。
<img width="1037" alt="スクリーンショット 2018-12-07 11.46.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/316760/fa2b7747-3b30-2756-e689-3cb9d782522e.png">

そうすると以下の画面になると思います。
<img width="1111" alt="スクリーンショット 2018-12-07 11.49.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/316760/bc101fbb-a818-54ff-34ec-53d84f876e07.png">

Titleは自分がわかりやすいように設定してください。
Keyは先ほど生成した.pubファイルをテキストエディタで開き、中にあるものをペーストしてください。
**※Keyをコピペする際に、無駄な改行を入れるとエラーが出るので気をつけてください。**
<img width="1205" alt="スクリーンショット 2018-12-07 11.59.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/316760/4f84021b-09eb-85a3-027d-7bb75710cae5.png">
こんな感じで怒られます。

##接続確認
これで設定は一通り終わったので接続できるか確認してみましょう。

```terminal
$ ssh github
Enter passphrase for key '/Users/*****/.ssh/id_rsa': 
PTY allocation request failed on channel 0
Hi mu-suke! You've successfully authenticated, but GitHub does not provide shell access.
```

こんな感じで表示されれば無事完了です。
操作方法とかは[Progate](https://prog-8.com/)にgitの学習コースがあるのでやってもらえれば理解できると思います！
お疲れ様でした！
あるページの画像をガッっと一気にダウンロードしようぜ！

あるWebページから画像をいっぺんにDLしたいときってあるよね！
いちいちマウスで右クリックして「名前をつけて画像を保存」をして、これを繰り返して、ってめんどくさいですよね。
ワンライナーで解決しましょう！

## 一括DLコマンド

```bash
curl -Ls $URL | xmllint --html --xpath '//img/@src' - | xargs -n 1 | cut -d= -f2 | sed 's/^\/\//https:\/\//' | xargs -n 1 curl -L#O
```

`$URL` がURL部分になりますので、目的のURLに置き換えましょう。

下は実行サンプルです。（注：読みやすくするために改行しています。）
DLしたデータを区別しやすいように、適当なディレクトリを作ってそのディレクトリ下で実行したほうがよいでしょう。

```bash:example
$ curl -Ls https://www.irasutoya.com/2015/11/blog-post_607.html | \
 xmllint --html --xpath '//img/@src' - | \
 xargs -n 1 | \
 cut -d= -f2 | \
 sed 's/^\/\//https:\/\//' | \
 xargs -n 1 curl -L#O
```

## ちょいと解説

### curl 

ご存知、Webページを取得するコマンド「カール」です。[^1]
`-L` で、リダイレクト指示されてもリダイレクト先の情報を取るようにします。
`-s` で、インジケータ（進捗状況を表すメモリ）を出さないようにします。
`-#` は、インジケータではなく`#`で作られた進捗メーターが出ます。（２つめのほうで使ってる）
`-O` は、ファイル出力です。ファイル名指定しないと、画像のファイル名を用いて保存します。（２つめのほうで使ってる）

### xmllint

XMLをパースするコマンドです。HTMLもパースできます。
`--html` で、htmlとみなしてパースします。
`--xpath` で、XPath [^aboutxpath] を用いて部分的にデータを抽出します。
`-` は、データとして（パイプから渡された）標準入力を用いることを指します。

[^aboutxpath]: XMLなどから特定の場所を抜き出したり指し示したりする場合に用いられる構文。[XML Path Language](https://ja.wikipedia.org/wiki/XML_Path_Language)。

### xargs

コマンドに渡す引数の最大値はOS依存で限界があります。コマンド `xargs` は、パイプ経由で与えられたデータを引数の列挙とみなし、一定の数でそれらを区切りながら、コマンドへ渡します。
ここでは、１行ずつ処理するために '-n' オプションを使っています。
`xargs -n 1` は、コマンドが省略されているので、暗黙的に `echo` が実行されます。[^2]
`xargs -n 1 curl` は、 `curl ...1個目...` `curl ...2個目...`と、順番にcurlが実行されます。

#### cut

ワンライナー使いの定番コマンドですな。
`-d`で示すデリミタで引数（主に文字列）を区切り、`-f n` で、n番目のものを抽出します（`n,m`や`n-m`とか`n-` とかといった複数指定も可能）
ここでは、`src="〜"`という文字列が渡されているので、`=`で区切った２番目の値 "〜" が続くコマンドに渡されます。

#### sed

こちらもワンライナーなどでよく使われる、元祖正規表現置換コマンド。[^3]
ここでは、URLが`//`で始まる場合に、（便宜的に）`https://`にするよう置換しています。

## エイリアス化

エイリアス（alias）化はできないです。URLとして引数を使うので。
なので手軽に使いたい場合は、`.bashrc` など、rcファイルに関数として登録するといいかもですね。

```bash:.bashrc
#関数サンプル（追加部分）
imgg() {
    curl -Ls $1 | \
    xmllint --html --xpath '//img/@src' - | \
    xargs -n 1 | \
    cut -d= -f2 | \
    sed 's/^\/\//https:\/\//' | \
    xargs -n 1 curl -L#O
}
```

## 使用上のご注意！

- HTML内の`<img>` だけを抽出し、そのsrc属性を参照しています。cssで定義されている画像やJavascriptなどで動的に読み込んだ画像（例えばGoogleの検索結果ページのようなもの）には対応していません。改造すればいけるでしょうけどここでは割愛。
- HTMLに構文的なエラーがある場合、標準エラー出力にxmllintのエラーが表示されますが、処理はそれを無視して進みます。
- 短時間に大量にアクセスすると、対象のサーバに負荷がかかりますので、良識の範囲で使いましょう！
- 画像やコンテンツには著作権があります。著作権を侵害しないように使いましょう！

（おわり）



[^1]: 長嶋茂雄氏の友達ではありません。
[^2]: なお、 `echo` の引数として与えられた時に`"〜"`が展開されるようで、結果的にダブルクォーテーションマークが削除されます。
[^3]: `sed`での置換はPerlでも表現可能で、かつ正規表現の機能も多く、記述も楽（エスケープしなくて良い）。なので、`sed`は使われる機会が減った印象。
MySQL、JSON型の最大長

# これはなに
MySQL 5.7のJSON型における最大長を調べたメモです。
MySQL8のことは調べてません。同じだと思いますが当環境はAmazon Auroraです。

# JSON型の最大値
ドキュメントによると、だいたいLONGBLOBとLONGTEXTと同じだそうです。
したがって、カラムの領域としては**4 GB**まで行けそうです。

https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html#data-types-storage-reqs-json
https://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html

# max_allowed_packet
JSON型をINSERTやUPDATEを行う場合は、SQLの最大長である`max_allowed_packet`に引っかかる場合がほとんどだと思います。
その場合、`max_allowed_packet`の最大値である**1 GB**が現実的な最大値となるでしょう。

https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
markdを使ってMarkdownからHTMLへ変換してみる

# やること

少し興味があったのでCrystalのMarkdownライブラリ[markd][]を試してみたいと思います。

[markd]: https://github.com/icyleaf/markd

# やっていく

## markdとは？

icyleaf氏作のMarkdownライブラリで、MarkdownからHTMLへの変換が行えるようです。

https://github.com/icyleaf/markd

JavaScriptのcommonmark.jsを参考にしているようですが、一部の機能はまだサポートされていないみたいです。

## インストール

`README.md`に書いてあるように、次の内容を`shard.yml`に追加して、`shards install`します。

```yaml:shard.yml
dependencies:
  markd:
    github: icyleaf/markd
```

## 使い方

`markd`を`require`して、HTMLに変換したいMarkdownの文字列を`Markd.to_html`に渡すだけです。

```ruby
require "markd"

markdown = <<-MD
# やること

少し興味があったのでCrystalのMarkdownライブラリ[markd][https://github.com/icyleaf/markd]を試してみたいと思います。
MD

html = Markd.to_html(markdown)
pp html
# => "<h1>やること</h1>\n" +
#    "<p>少し興味があったのでCrystalのMarkdownライブラリ<a href=\"https://github.com/icyleaf/markd\">markd</a>を試してみたいと思います。</p>\n"
```

また、いくつかオプションがあって、それらを渡すと挙動が変わるみたいです。

例として`safe`オプションを有効にしてみると、HTMLの部分がざっくり削れました。

```ruby
require "markd"

markdown = <<-MD
# Twitterへのリンク

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">最近はただ、妹のことだけを考えていたい</p>&mdash; さっき作った (@make_now_just) <a href="https://twitter.com/make_now_just/status/638132806812495873?ref_src=twsrc%5Etfw">2015年8月30日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
MD

option = Markd::Options.new(safe: true)
html = Markd.to_html(markdown, option)
pp html
# => "<h1>Twitterへのリンク</h1>\n" +
#    "<!-- raw HTML omitted -->\n"
```

他のオプションなどは[markd][]の`README.md`を確認してください。

また、自前で`Renderer`を定義して出力をカスタマイズすることもできるみたいです。

# まとめ

CrystalのMarkdownライブラリ[markd][]を使って、MarkdownからHTMLへ変換してみました。

実はCrystalの標準ライブラリにも`Markdown`というモジュールがあって、MarkdownからHTMLへの変換ができるのですが、実装が微妙なためMarkdownの多くの機能に対応していないのが辛いところです。
この`Markdown`モジュールは主にドキュメントジェネレーターで使われているのですが、前述した通り微妙なので、markdで置き替えようという動きがあったりします。
そのための調査を含めて使ってみたのですが、markdもまだやや機能が足りない部分がある気がしたので、機会があればコントリビュートしたいところです。

というわけでCrystal Advent Calendarの5日目でした。
6日目もいません。追いつけるのか？

最後まで読んでいただきありがとうございました。
aspell no sudo install

## やったこと

```console

mkdir /home/user_name/src
cd /home/user_name/src
wget ftp://ftp.gnu.org/gnu/aspell/aspell-0.60.6.1.tar.gz
tar xvfz aspell-0.60.6.1.tar.gz
cd aspell-0.60.6.1/
mkdir /home/user_name/aspell
./configure --prefix=/home/user_name/aspell --bindir=/home/user_name/bin
make
make install
which aspell

```

## 参考

https://www.sitepoint.com/forums/showthread.php?378959-how-to-install-aspell-on-linux
Operation as a code 実現に向けた運用統合ライブラリの作成活動について

この記事は [富士通クラウドテクノロジーズ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/fjct) の10日目です。　　
昨日は @khamanaka　さんの　エンジニアリングマネージャーとして1 on 1で使ってきた「好き/嫌い/得意/苦手のマトリクス分析」　でした。

## 概要
インフラSRE部　新卒2年目の@jinshiです。
タイトルで勝手に「Operation as a code」とつけてますが、運用に必要なオペレーションをコードとして表現しようという活動です。
私のチームではSRE活動の一環として、運用のオペレーションをコードで表現するために運用統合ライブラリーなる物を作成する活動をしています。
まだ製作段階ですが本記事ではその統合ライブラリーについて紹介したいと思います。

## 背景

私のチームでは日ごろ様々なサービスを管理・運用してきました。
今までも増加する管理対象に対応するために個人、チームレベルでは運用を効率化するために手動で行っていた作業をスクリプト化する活動は一部でありました。
たとえば構築作業などは一部分はツール(ansible)などを使用してコードとして実現されています。
しかし初期の段階でこれらスクリプトの設計や規約などを設けなかったため様々な問題がでてきました。

- 特定のインターフェースからしか実行できないコードがあり、違うインターフェースから実行するには同じようなロジックを複数のファイルに書く必要がある
  - 例えばansibleとcliから同じコードを実行したい場合など
- コードがいろいろなプロジェクトに分散しており管理が煩雑になる
- etc

またこの問題点に加えて、まだスクリプト化されてない運用手順も多くあり日々複雑で肥大化する管理対象に耐えられなくなる可能性がでてきました。
このような問題を解決するために統合ライブラリーを作成する活動がスタートしました。

## 統合ライブラリーで実現したいこと

### 効率化
- 手順がアップデートされた際の共有
	- 更新されたコードを実行ノードに配布するだけになる
- テスト・CI(今まで手順書などを人が確認していた部分がCIで自動化できる)
	- コンポーネントのアップグレードや入れ替えで以前の運用が継続できるか検証が必要だが工数が大きかったが、CIなどの取り組みにより素早くできるようにする
- 運用オペレーションの自動化(人が作業をする必要がない状態)

### サービス品質
- 障害が起こった際の対応スピードの向上
- CI(テスト自動化)によるオペレーションの信頼性の向上
- 効率化により新サービスや新機能に注力できる時間を増やせる

### 非属人化
- 運用オペレーションの非属人化・運用ノウハウ伝播の効率化
	- コードを見ればオペレーションのロジックが追えるので今まで個人の頭の中にあった運用ノウハウをチームメンバーが知れるようになる

## 設計
大きな設計の概要図は以下になります。  
![設計.png](https://qiita-image-store.s3.amazonaws.com/0/30193/7da2ea1c-0c4c-eb9b-e7f3-d4fad26618f6.png)

### アダプター

- 各インターフェースに一つ作成する形になると予想しています。
- controllerの情報を読み取り各インターフェースから実行できるようにします。
- 正確にはライブラリの外の機能になりますが実際に使用するにあたっては必要になってくるので、実装予定です。
    - 今考えてるところですと、CLI, APIサーバーの自動生成, Ansible モジュールの自動生成あたりを考えています。

### Controller

- 実際にロジックをかいていくとこです。
- また入力、出力の定義、バリデーション機能などを含める予定です。
- 実際にサービスを操作するためのDAOを呼び出します。
- 1 controllerはDAOの1操作(1API)に対応させようと考えています。複数のサービスの操作が必要な場合はコントローラーが他のコントローラーを呼ばせるように規約を作ろうと思います。

### DAO

- 各サービスのAPIへのアクセスなど、各サービスの操作をする部分です。

## 課題

実際に規約をコードとして表現する部分が難しいところです。
コードをレビューする際に実際に動作するコードであるかの確認はあたりまえですが、可読性や上で示した設計通りになっているかなど規約を確認する必要があります。
その確認を毎回人がするのは大変で時間がかかるためコードとして確認できる仕組みを実現できするのが理想です。

しかしあまりに強い規約や、規約に従わせるために無理な実装があるとチームメンバーの開発の負担になります。
オペレーションをコード化したチームが「コードを書くコストが思った以上に高く結局手動より時間がかかってしまっている。」なんていう例も聞いたことがあります。
またその場合他チームへの展開もしにくくなってしまいます。

最初はチームに閉じて利用していきフィードバック、メンバーの使用感や意見をもらいつつ設計を変更していく必要があると思っています。

## まとめ

まだ実際に実装は終ってはいないですが、近日中に実際に統合ライブラリを利用してのオペレーションを予定しています。
またチーム内での実績が積め安定した利用が見込める場合は他チームへの展開などをしていきたいと思っています。
特にアダプター部分を強化していくことによりロジックを考える部分に集中ができ他のチームが利用した際にもメリットがある内容になるのではないかと思っています。

11日目は@pachicourseの 「0知識からのAnsible 詰まった所&覚えておきたいと思ったところ列挙編」です！
タイトルを見た感じ弊社の違うチームもAnsible使ってるようですね。本記事の活動が他チームにも広がるとうれしいです。
超簡単なバージョンの付け方

#超簡単にバージョンを付ける

##数字の上げ方

###3つの数字を使う

```:1
0.0.0
```
こんな感じ。3つの数字だとシンプルで管理も楽になる。
数字の間は**`.`**で区切る。

###小型アップデート

```:4
0.0.1
```

右の数字を1つ上げる。

###大型アップデート

```:3
0.1.0
```

真ん中の数字を1つ上げる。

###アップデートで前回のバージョンと互換性が無くなった場合(または超大型アップデート)

```:2
1.0.0
```

左の数字を1つ上げる。

大きいアップデートがあるごとに小さいアップデートの値は0に戻される。

##補助記号の付け方

###製品版を出せるレベルではない未完成なもの

```:5
1.1.1α
```

1番右に**`α(アルファ)`**をつける。

###製品版として出す前段階(不具合があったりするもの)

```:6
1.1.1β
```

1番右に**`β(ベータ)`**をつける。

###製品版

```:7
1.1.1
```

補助記号はいらない。
Excelにテキストで貼り付けるときにセル内改行させる方法

# Excelでテキストで貼り付けるときにセル内改行させる方法

一瞬悩んだのでメモ

## 環境
Mac Hi-Sierra
Excel for Mac バージョン16.16.4

### 方法
1つのセルにしたい行をダブルクオーテーションで囲めばOK

```
1行目
2行目
"3行目
3行目のセル内改行
3行目のセル内改行その２"
4行目
```

### 貼り付け結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/3094/6b204fdc-2ab1-4876-11ac-e6ee1960d7ef.png)

泥臭い作業をするには便利。。。
EC-CUBE4 セッション情報の出力先をデータベースに変更

**"[EC-CUBE 4.0 開発者向けドキュメントサイト](https://doc4.ec-cube.net/session_handler_settings)" に記載されるようになりました。**

---

## まえおき

EC-CUBE4のセッション管理のデフォルトはファイル書き出しになっているので、Webサーバーの冗長化などを行ったときには各サーバーでセッション情報を管理してしまうと問題が発生するケースがあります。

そのため、セッション情報の書き出しを `ファイル` から `データベース` に変更します。

## 作業

１. `PdoSessionHandler` にデータベースの接続先を伝える

```yaml:app/config/eccube/services.yaml
# ↓ここから
    Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
        arguments:
            - '%env(DATABASE_URL)%'
# ↑ここまでを追記
```

２. `session` に `PdoSessionHandler` が使われるようにする


```yaml:app/config/eccube/packages/framework.yaml
    session:
# ↓ここから
#        handler_id: session.handler.native_file
#        save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
# ↑ここまでをコメントアウト

# ↓ここから
        handler_id : Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
# ↑ここまでを追記
```

３. インストーラー実行時は、ファイルシステムが使われるようにする

```yaml:app/config/eccube/packages/install/framework.yaml
framework:
  session:
    handler_id: session.handler.native_file
    save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
```

４. マイグレーションファイル作成

```bash
php bin/console doctrine:migrations:generate
```

```php:app/DoctrineMigrations/VersionYYYYMMDDHHMISS.php
    public function up(Schema $schema) : void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->addSql('CREATE TABLE `sessions` (
    `sess_id` VARCHAR ( 128 ) NOT NULL PRIMARY KEY ,
    `sess_data` MEDIUMBLOB NOT NULL ,
    `sess_time` INTEGER UNSIGNED NOT NULL ,
    `sess_lifetime` MEDIUMINT NOT NULL
) COLLATE utf8_bin, ENGINE = InnoDB');
    }

    public function down(Schema $schema) : void
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->addSql('drop table sessions');
    }
```

５. マイグレーション実行

```bash
php bin/console doctrine:migrations:migrate
```

以上です

---

参考：
https://symfony.com/doc/current/doctrine/pdo_session_storage.html
Bundler まとめ

Ruby on Rails を始めて環境構築をしているときに出てきた Bundler。
Bundlerってなんやねん。って思ってましたが、ようやく理解できてきたのでまとめます。

# Bundlerとは
簡単に言うと、gemのパッケージ管理システム。
gem同士の互換性を保ちながらバージョン管理してくれるので、Ruby on Railsの環境構築ではとっても便利。

# 本家サイト
https://bundler.io/

# Bundlerのインストール
Bundlerはgemなので、gemコマンドでインストールします

```
$ gem install bundler
```
Bundlerだけgemコマンドでインストールして、他のgemはBundlerでインストールするイメージ
以下のコマンドでインストールされたかどうか確認

```
$ bundler -v
```

# Bundlerの使い方

### Gemfileの作成
Gemfileとは、インストールするgemを記載するファイルです
※既にある場合は読み飛ばしてください
※Ruby on Rails の場合は、railsコマンドでプロジェクト作成時に一緒に作成されます

以下のコマンドでGemfileの雛形が作成できます

```
$ bundle init
```

### Gemfileの記載方法
書き方の例を以下にインラインで記載します

```ruby:Gemfile
source "https://rubygems.org" # gemインストール元URLを記載する 【必須】

ruby '~> 2.4' # Rubyのバージョンを記載
# 指定しておくと、別のRubyバージョンでGemfileが読まれたときに例外を発生させることが出来る

########################################
# 各インストールしたいバージョンの書き方
########################################
gem 'rails', '5.2.2'    # 5.2.2 固定

gem 'rails', '>= 5.2.0'              # 5.2.0 以上の最新
gem 'rails', '>= 5.2.0', "< 5.2.2"   # 5.2 以上、5.2.2 未満

gem 'rails', '~> 5.2.2' # 5.2.2 以上、5.3.0 未満の最新
gem 'rails', '~> 5.2'   # 5.2 以上、6.0 未満の最新
# 記載した一番末端の数値のみ最新に追従するということ

########################################
# Ruby on Railsの各環境別の書き方
########################################
# dev環境のみに反映したいgem
group :development do
  gem 'hoge'
end

# dev環境とtest環境に反映したいgem
group :development, :test do
  gem 'hoge'
end
```
他にも様々な書き方があります
詳しくは https://bundler.io/v1.17/man/gemfile.5.html を参照してください


### Bundlerによるgemのインストール
以下のコマンドでgemをインストールすることが出来ます

```
$ bundle install --path vendor/bundle
```
- --pathでgemのインストール先を指定することが出来ます  
コマンドを実行した場所に vendor/bundle ディレクトリが作成され、そこへgemがインストールされます  
 - --pathは一度指定したら保持されるので以降は不要
 - --pathを指定しなかった場合、システムのRubyに依存したパスへインストールされる  
※rbenvを使っていると以下のようなパス  
~/.rbenv/versions/\<current version>/lib/ruby/gems/...
 - なぜ vendor/bundle なのかというと、vendor ディレクトリは一般的に自身が開発しているものではないサードパーティのライブラリを入れる先として使われていて、そこへBundler用のbundle ディレクトリを作成してインストールするのが慣習っぽい
- Gemfile.lockが存在しない場合、コマンド実行時にGemfile.lockが生成されます
 - Gemfile.lockとは、Gemfileに記載したgemと依存関係にあるgemを含めたすべてのgemの名前とバージョンが記載されたファイルです
 - プロジェクトではGemfile.lockの情報が使われます

### インストールしたgemのコマンド呼び出し
Bunderでインストールしたgemで使えるようになったコマンドを呼び出したい場合は、
以下のように「bundle exec」をつけて実行します
※コマンド名は各gemの説明を参照してください

```
$ bundle exec rails -v
```

### 各コマンドについて
| コマンド | 内容 |
|:-----------------|:------------------|
| bundle install | Gemfile.lockが存在しない場合、Gemfileを元にgenのインストールを行う。<br>Gemfile.lockが存在する場合、Gemfile.lockになくGemfileに記載されている<br>gemがある場合、そのgemと関連するgemをインストール後、<br>Gemfile.lockを更新します。<br>※Gemfile.lockに既にあるgemは更新されない |
| bundle update | Gemfileを元にgemのインストールをします。<br>gemインストール後、Gemfile.lockを更新します。<br>※Gemfile.lockに既にあるgemが更新されるので実行時は注意 |
| bundle update [gem name] | 特定のgemのみupdateしたい場合は、gem nameを指定する。 |
| bundle list | インストールされているgem一覧を表示する |

### Bundlerでインストールしたgemを全てやり直したい場合
単純に vendor/bundle ディレクトリを削除してインストールし直せば良い

```
$ rm -d -R vendor/bundle
$ bundle install
```
Digdag x Luigi x Beam が協力して賢者の石を取りに行くのをやめた

### TL;DR

- 前任者が闇の魔法使いだったという話
- Workflow Engine は混ぜるな危険
- ポエムなのでコードとかない
- 出てくる言葉については語らないのでいくらか前提知識が必要

### Prologue

「ハリー・ポッターと賢者の石」でハリー・ポッター、ロン・ウィーズリー、ハーマイオニー・グレンジャーの三人はそれぞれが役割を分担してパスを繋ぎ賢者の石へと辿り着いていました。

Workflow Engine と呼ばれるようなものはようはそういう風にタスクで処理を独立させつつ順序に従って処理するための仕組みですね。

例えば YAML ベースの Digdag とか、 Python で記述する Luigi とか、Java や Python で Cloud Dataflow (Apache Beam) とか色々あります。

私は最近 **これ** を使ってログを分析して賢者の石に辿り着くためのデータ分析基盤の担当にアサインされたわけです。

**これ** とは、

- Digdag
- Luigi
- Cloud Dataflow (Apache Beam)

です。

お察しかと思いますが、担当しているデータ分析基盤は何と、 Workflow Engine が 3 つ使われて連結して出来ているのでした。

一体どうなるのでしょう。

... ＼(^o^)／

### 処理の流れ

図にするのはめんどくさかったのですみません。

1. BigQuery にデータがたまる
2. GKE (GCP のコンテナサービス) 上の Digdag コンテナが定期的にタスクを実行する
    1. タスク内では処理内容毎ステップが存在する
    2. 各ステップは Python を実行する
    3. Python は GKE に Luigi コンテナか Cloud Dataflow コンテナを起動する
3. Luigi コンテナ) Luigi を使った Python が実行される
    1. 処理に必要な情報を取得する API などをコールする
    2. BigQuery 上のデータにクエリを実行して処理結果を保存する
    3. クエリがいくつか必要な処理は Apache Beam で更にワークフロー化してクエリ実行する
4. Cloud Dataflow コンテナ) shell script を介して Apache Beam を使った Java が実行される
    1. BigQuery 上のデータにクエリを実行して処理結果を保存する
    2. ものによっては shell script で完結してたりする

### 読んだ時の感想

＼(^o^)／

#### 実際これで、何がオワッテたのか

(Workflow Engine とか関係なくコーディングとかで目に余る部分は割愛)

- Workflow Engine 毎に思想が違うから緩衝材に使われてる Python の書き方が場所によって異なるのでコードを追いにくい
- 4. に至っては何故か Java が顔を出して来るので言語が変わって更に読みにくい
- 更に言うと 3. 4. で使う Cloud Dataflow は言語が別なので、 Cloud Dataflow は両方の書き方を覚える必要がある
- 上記の 2. 3. 4. は全て別のリポジトリで管理されてるので処理が追いにくい。本当に。
- 全てで Cloud Dataflow まで使うならまだしも、一部なので、 Cloud Dataflow の UI から見ても全てのデータの処理は可視化されない
- Digdag コンテナの死に実行中タスクが影響されない仕組みだが、そもそもタスクを分割しきれてないため、タスク用コンテナ内で更に Workflow Engine が動く羽目になっている
- Bigquery でクエリを実行してるだけなのにコード化することで複雑に見える
- ソースの階層が深くなり過ぎていつまで経ってもSQLに辿り着かない

### どうしたか

- Digdag コンテナを常時起動するのではなく、 [CronJobs](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) でスケジューリング
- ワークフローは Digdag で完結させる
- Python とか呼ばないで直接 bq コマンドを使う

#### CronJobs にした理由

- Digdag コンテナはバッチサーバーだったわけですが、これが落ちた時に何がスケジュール実行されなかったのか分かりにくかった
    - CronJobs にしちゃえば落ちるのは特定の Job になる
- どの処理にどれだけのリソースが消費されるのか分からなかった
    - CronJobs にしちゃえばその単位でモニタリングされるので確保すべきリソースが分かる
- 常時起動しているサーバーを管理したくなかった

#### Digdag + bq コマンド にした理由

- Yaml なのでコードよりシンプル
- 基本は BigQuery 上でのクエリ実行なのでコードにしなくても bq コマンド使っていれば十分
    - Digdag の bq プラグインは bq コマンドと同等のことができないので個人的にはオススメしない

### Epilogue

- やってること、やりたいことに見合わない複雑さは要らない (ハリポタの賢者の石は適切に役割分担してると思います)
Rubyでスレッドをデバッグする

環境

- Ruby 2.5.0
- byebug 10.0.2

byebugにはスレッドをデバッグするために `thread` というコマンドがあり、以下の機能がある。

>デバッガーでthread(短縮形はth) コマンドを使用すると、スレッド実行中にスレッドのリスト表示/停止/再開/切り替えを行えます。このコマンドには以下のささやかなオプションがあります。
>
>threadは現在のスレッドを表示します。
>thread listはすべてのスレッドのリストをステータス付きで表示します。現在実行中のスレッドは「+」記号と数字で示されます。
>thread stop nはスレッド n を停止します。
>thread resume nはスレッド n を再開します。
>thread switch nは現在のスレッドコンテキストを n に切り替えます。
>https://railsguides.jp/debugging_rails_applications.html#%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89

# 使用例

```hoge.rb
# デッドロックするスクリプト

require "byebug"

threads = []

m1 = Mutex.new
m2 = Mutex.new

threads << Thread.new do
  m1.synchronize do
    puts "thread1: enter m1.synchronize"
    sleep 1
    m2.synchronize do
      puts "thread1: enter m2.synchronize"
    end
  end
end

threads << Thread.new do
  m2.synchronize do
    puts "thread2: enter m2.synchronize"
    sleep 1
    m1.synchronize do
      puts "thread2: enter m1.synchronize"
    end
  end
end

# 普通、スレッドの終了待ちするときは threads.each {|t| t.join } のように書くと思うが、デバッグするためにこの待ち方をしている
while threads.any? {|t| t.alive? }
  puts "waiting..."
  sleep 1
  #byebug
end

puts "end"
```

上記のスクリプトは2個のスレッドを作成しており、それぞれ`m1, m2` `m2, m1`の順でmutexロックを取得しようとするので、デッドロックする。実際に実行すると次のような出力になる:

```console
$ ruby hoge.rb
waiting...
thread1: enter m1.synchronize
thread2: enter m2.synchronize
waiting...
waiting...
waiting...
waiting...
waiting...
（永久にwaiting...が続く）
```

これをデバッグするため、スクリプトの`# byebug`の行のコメントアウトを外して実行する。


```console
$ ruby hoge.rb
waiting...
thread1: enter m1.synchronize
thread2: enter m2.synchronize

[21, 30] in /Users/val00362/hoge.rb
   21:       puts "thread2: enter m1.synchronize"
   22:     end
   23:   end
   24: end
   25:
=> 26: while threads.any? {|t| t.alive? }
   27:   puts "waiting..."
   28:   sleep 1
   29:   byebug
   30: end
(byebug) th list
+ 1 #<Thread:0x00007fd8c107dd38 run> /Users/val00362/hoge.rb:26
  2 #<Thread:0x00007fd8c08a16f0@hoge.rb:8 sleep_forever> hoge.rb:11
  3 #<Thread:0x00007fd8c08a1538@hoge.rb:17 sleep_forever> hoge.rb:20
(byebug) th sw 2
  2 #<Thread:0x00007fd8c08a16f0@hoge.rb:8 sleep_forever> hoge.rb:11
waiting...

[21, 30] in /Users/val00362/hoge.rb
   21:       puts "thread2: enter m1.synchronize"
   22:     end
   23:   end
   24: end
   25:
=> 26: while threads.any? {|t| t.alive? }
   27:   puts "waiting..."
   28:   sleep 1
   29:   byebug
   30: end
(byebug) bt
--> #0  block in block in <main> at /Users/val00362/hoge.rb:26
    ͱ-- #1  Array.any?(*args) at /Users/val00362/hoge.rb:26
    #2  <main> at /Users/val00362/hoge.rb:26
```

メインスレッドの`byebug`のところでデバッガが起動するので、`th list`でスレッド一覧表示、`th sw 2`でスレッド切り替え、`bt`でバックトレース表示（今どこを実行中か確認）している。
webfontのサブセットにない文字の表示はどうなるか？

# 主眼
webfont は日本語においては文字数が多く、ファイルサイズも大きくなるという理由でサブセット化（よく使う文字だけ抜き出してカスタマイズしたものを作る）が必須っぽくなっているけれど、 **そこから漏れた文字の表示はどうなる** のだろう？

そんな訳で、「たぶんこうなるんだろうな」と思ったけど、実際にやってみた。

# webfont is 何
これまでのブラウザ上での文字の表示は、クライアント依存でした。OSに標準的に搭載されているフォント、ユーザーが追加したフォントから表示されていました。特別なフォントは画像化していた訳ですが、webfontならテキストのままデザインフォントを適用できるので、画像に比べて容量が少なく、検索エンジンのクローリング対象になるので、メリットが多いのです。

# Google Fontsに行く

Googleが世界を支配するんじゃないかっていうのが本当になりそうだ、と思うくらい、Googleには何でも揃っています。
そう、 webfont もね。

ということで、Googleさんお墨付きの webfont のサイトがこちら。なんと904フォントも。(2018年12月7日現在）
https://fonts.google.com/


ただし、日本語対応のフォントは少ないです。12フォント。

（※ 2019年9月27日に「いいね」をもらったので、改めて見てみたら、8フォントになってました。減ることってあるんですね……）

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/bea14e54-03a0-96a6-6735-a704fe961256.png) |
|:-:|

最初から日本語対応のフォントにアクセスしたい場合はこちら↓
https://fonts.google.com/?subset=japanese

# フォントをダウンロードする
1. 気に入ったフォントの右上の＋マークをクリック
2. 「1 Family Selected」と書かれたモーダルがもこっと登場するのでクリック
3. 右上の↓（ダウンロードアイコン）をクリック
4. zipファイルがダウンロードできる

私の場合は、 'Kosugi Maru' フォントをダウンロードして、解凍したら KosugiMaru-Regular.ttf というファイルが出てきました。

# サブセット化する
・サブセットフォントメーカー
https://opentype.jp/subsetfontmk.htm
・WOFFコンバータ
https://opentype.jp/woffconv.htm

サブセットを作って、それをwebfontにします。
引っかかったのが、「サブセットフォントメーカー」の「フォントに格納する文字」です。
自分で入力しないといけないんですが……

下記URLにあるからそれを使うと良いよ！と書いてあったのですが、超人気だからかまったく繋がらずにタイムアウトしてしまいます。
https://11neko.com/font-3/

今回はサブセットにない文字の表示を確認したいので、むしろサブセットの文字は少なくて良い、ということで。
**「あいうえお」**
としました。

このサイトのありがたいところは、 **サンプルHTMLファイルを作成する** というメニューが用意されていること。

# 表示してみる

分かりやすくするために、フォントサイズを88ピクセルにしてみました。

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style type="text/css">
@font-face {
  font-family: "myFont";
  src: url("subset.woff2") format('woff2'),
       url("subset.woff") format('woff');
}
.myFontClass {
  font-family: "myFont";
  font-size: 88px;
}
</style>

<body>
<p>サンプル文字列は「<span class="myFontClass">あいにうえている</span>」です。</p>
</body>
</html>
```

![スクリーンショット 2018-12-07 10.13.31.png](https://qiita-image-store.s3.amazonaws.com/0/90217/9df90dae-4cea-de4d-fdc9-df40ab9a9f00.png)

最初はサンプル文字列を「あいうえおかきくけこ」にしたんですが、混ぜたくなったので、「あいにうえている」にしてみました。「あい」「うえ」「い」と、それ以外のフォントの違いが分かると思います。サブセットにないものは、通常のフォントで表示されます。
最初の「たぶんこうなるんだろうな」の通りでした。

# 追伸
愛に飢えているのは本当です。
Vue.jsで絵文字をクリックするだけのクソゲーを作りました

「[クソアプリ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/kuso-app)」7日目の担当、黒神([@kokushing](https://twitter.com/kokushing))です。

みんなクソ（クオリティ高い）アプリを作っているので、僕も負けじと頑張りましたが、技術力に限界がありどうしようもないクソアプリができてしまいましたので先にお詫び申し上げます。

## 作ったもの

「Emoji Wars」というブラウザゲームです。

[Emoji Wars](https://kokushin.github.io/emojiwars/)

![emoji.gif](https://qiita-image-store.s3.amazonaws.com/0/57867/0d2e5f8c-f86e-b15d-296c-209bfe2d27b1.gif)

ただただ絵文字をクリックして点数を稼ぐというクソゲーです。
5回絵文字をクリックするとフィーバーモードに突入して獲得点数が10倍になります。

ぜひ高得点を競い合ってみてください😂

## 使った技術

- Vue CLI 3 (Vue.js + Vuex, babel + webpack)
- GitHub Pages

今回使ってみた技術の目玉は__「Vue CLI 3」__です。
VueFesで公演を聞いたときから興味があったのですが、実際に一回も使ったことがなかったのでこの機会に触ってみました。

結論から言うと、めっちゃ使いやすかったです。特に__「Vue CLI UI」__が。
メリットをざっくりとまとめておきます。

- GUIなのでポチポチするだけでVue.jsの開発環境が整う
- 各種モジュール（vue-router, vuexをはじめ、npmで公開されているパッケージ等）をポチポチするだけでインストールできる
- ビルドやリントなどのコマンド群もGUI上で実行できる
- 日本語対応済み

vuexやvue-routerなんかは途中から追加したいときに、毎回自前でディレクトリやファイル用意するのが面倒くさかったので、数クリックで簡単にインストールできるというのは素晴らしいなあと思いました。

## vue.config.js

Vue CLI 3ではwebpack.config.jsなどの設定ファイルがプロジェクトディレクトリ内に生成されないので、__vue.config.js__という設定ファイルを自前で用意する必要があります。

今回はGitHub Pagesでホスティングしたかったので、docsディレクトリにビルドしたものを吐き出すようにconfigを変更しました。

```js
module.exports = {
  baseUrl: process.env.NODE_ENV === 'production'
    ? '/emojiwars/'
    : '/',
  outputDir: 'docs'
}
```
`baseUrl`は環境変数に応じてディレクトリのパスを切り替えるようにしています。
`outputDir`でビルド後のファイルが吐き出されるディレクトリ名を指定しています。

他の設定項目は公式ドキュメントをご覧ください。
https://cli.vuejs.org/config/

## 感想

Vue js 幸せ

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">vue js 幸せ <a href="https://t.co/l4ONueyqaR">pic.twitter.com/l4ONueyqaR</a></p>&mdash; 黒神 (@kokushing) <a href="https://twitter.com/kokushing/status/1070504806492459009?ref_src=twsrc%5Etfw">2018年12月6日</a></blockquote>

__追記:__
クソゲーに需要が生まれました。
全国のFPSプレイヤーの皆様、ご活用ください

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">これエイム練習に最適です！！フリックショットといって、マウスを瞬時に動かして敵にカーソルを合わせる技術が鍛えられる！しかも顔文字だからヘッドショット気分が味わえる！なんて素敵なんだ</p>&mdash; もいもい (@_CrMoi90) <a href="https://twitter.com/_CrMoi90/status/1070860347462971392?ref_src=twsrc%5Etfw">2018年12月7日</a></blockquote>

## クソコードはこちら

https://github.com/kokushin/emojiwars

## 他に作ったもの

クソからマジメまで、いろんなものを作ってます。
https://yusukeishiguro.com/

__Tapbox__
Tapboxは「決められた回数タップしないと開かない箱」を簡単に作成することができるサービスです。
https://tapbox.app/#/

__makepost__
つくったものをシェアできるSNS（リニューアル予定）
https://www.makepost.net/

---

黒神先生の次回作にご期待下さい！

明日は　@watanabe_yu　さんのクソアプリです。楽しみ🤪
わずかなダウンタイムで第1世代CloudSQLを第2世代へアップグレードできるようになってた

[Ubiregi Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ubiregi) の7日目の記事です。

先日管理コンソールを眺めていると、AWSのドキュメントにあるような [わずかなダウンタイムでの MySQL データベースのアップグレード](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.MySQL.html#USER_UpgradeDBInstance.MySQL.ReducedDowntime)と同じ方法でアップグレードができるようになっていました。


2018年8月くらいの時点では、このようなアップグレードのためのツールは提供されておらず、サービスを停止してダンプをエクスポートしてインポートしろ、というパスしか用意されていなかったと思います。
https://cloud.google.com/sql/docs/mysql/upgrade-2nd-gen#performing_the_upgrade

これ使えばアップグレードが楽に出てきて便利。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/42642/8f82f5aa-de28-67a7-6cd4-fe174a4e7969.png)


以上。
Vimのおまじない(プラグイン作者向け)

プラグイン作成で気付いたことがあったら追記していく。

## プラグイン・オプションの設定

いまだと次のようにプラグインのオプションを定義する

```vim
let g:hoge = get(g:, 'hoge', 1)
" g:hogeが定義してあればその値、なければデフォルトで1にする
```

ここで次になるので注意

```vim
let g:hoge = 0
let g:hoge = get(g:, 'hoge', 1)
echo g:hoge " 0

let g:hoge = 0
let g:hoge = get(g:, 'hoge ', 1)
"_________________________^_____ スペースがある
echo g:hoge " 1
```

`execute`的にスクリプトが処理するんじゃなく、純粋に文字列として処理されてるっぽい(機能からしてg:というディクショナリの検索だからまあそうだけど)
気付くのに時間がかかった...😢
Application InsightsをPHPのシステムに組み込む ～基本情報とテレメトリの整理編～

## はじめに
PHP製のWebAPIのシステムで各種調査（不具合調査、速度調査など）を行うとき、既存のテキストベースのログだと流石に辛くなってきたなーと感じてたところで、AzureのApplication Insightsを使う機会があったので採用することになった。
その調査過程などをメモがてらまとめます。

## Application Insightsの基本情報
### そもそもApplication Insightsとは
[Azure Application Insights とは何か | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/application-insights/app-insights-overview)
以下引用
> Application Insights は、複数のプラットフォームで使用できる Web 開発者向けの拡張可能なアプリケーション パフォーマンス管理 (APM) サービスです。
このサービスを使用して、実行中の Web アプリケーションを監視することができます。 パフォーマンスに異常があると、自動的に検出されます。
組み込まれている強力な分析ツールを使えば、問題を診断し、ユーザーがアプリを使用して実行している操作を把握できます。
Application Insights は、パフォーマンスやユーザビリティを継続的に向上させるうえで役立つように設計されています。

### メリット
- ログ情報が構造化されているのでパラメータの集計や検索（フィルタリング）がやりやすい。  
  ⇒ 特に例外時のトレース情報は便利すぎる
- 同一API内でのログが自動的にグルーピングされるので前後関係が追いやすい

### デメリット
- PHPに限って言うとSDKの開発に力が入っておらず、今後もサポートされるかという点が際どい
- ログの情報量に応じてサーバ送信コストが掛かるため、どうしても処理が全体的に重くなる  
  ⇒ 解決策は試行錯誤しているのでいずれまた
- 従量課金なのでシステム規模によってはコストが掛かる  
  ⇒ とはいえだいぶ安いみたいだが、正直コスト計算がよくわからない…
- 多少のラグがある  
  ⇒ Azure Portalで確認できるようになるには数分待つ必要があるので組み込みの確認中は微妙なストレスがあるものの、本来の使い方的には影響はない
- 便利すぎて調子に乗ってログを吐きすぎちゃう

## テレメトリの種類について
これまでログと言ってたけど、Application Insights的には正しくはテレメトリ。
種類が沢山あるほか、基本的にApplication Insights自体がC#での使用を推奨しているためPHPのSDKを踏まえた使い方の目安も交えて整理する。

- `Trace`（トレース）  
    Applicationの内部ログ  
    主に操作の流れを追跡するために利用する  
    他のテレメトリと違い、いわゆるログレベルが指定できる（`severityLevel`）  
    弊社のシステムでは今の所MethodのIN/OUTのみ使用しているが、重要な分岐などに入れるのも効果的だと思われる  
- `Request`（要求）  
    外部のURLにリクエストを送るとき利用する  
    システムから外部のWebAPIをCallする際に  
- `PageView`（表示）  
    WebAPIでは不使用でいいと思われる（WebAppならば、おそらくRenderのタイミングで出力するのでは）  
- `Custom Event`（カスタム イベント）  
    基本的に自由に使えると思われる  
    あるポイントでのパラメータなども確認する用途もこれでいいと思われる  
    弊社のシステムではAPIの入り口での全パラメーターの記録と、APIの出口で使用したメモリ量、Query発行数を記録するようにしている  
    （`Trace`を使っていないのは、`Trace`には計測情報の付与ができなかったため）
- `Exception`（例外）  
    例外発生箇所やStackTraceが取得できる（C#ならダンプまで取れるかもしれないがPHPでは無理っぽい）  
    例外発生時には自動的に処理されるのが望ましいが、おそらくTry/Catchで明確に処理しているところでは手動で追加する必要がありそう（もしかするとC#辺りだと自動的に全部処理してくれるのかも）  
    弊社のシステムではコード中でcatchしそこなったものは自動的に出力するようにしている
- `Dependency`（依存関係）  
    外部コンポーネント（主にDB）の呼出時間などを記録する  
    パフォーマンス劣化に主要因であるQueryの発行状況を細かく観察できるので一番有益なテレメトリ  
    前述した`Request`と多少混同するが、`Request`はHTTP経由の外部サーバについか、それ以外は`Dependency`だと思われる  
- `Availability`（可用性）
    公式の解説では出てくるテレメトリなのだが用途がイマイチ理解できていないし、PHPのSDKでの指定方法も不明  

- `Metric`（測定基準）
    キューの長さなどのパフォーマンス収集に使用する
    前述した使用メモリの計測やQuery発行数の記録は本来こちらを使うべきなのかもしれないが、.NET SDKでは`trackMetric()`が非推奨になっているため使うのが憚られるので、弊社システムでは未使用

今回は一旦ここまで。
次回はPHPのSDKの使い方の具体例を交えてまとめる予定です。
Vim の :terminal の色を設定する方法

この記事は Vim Advent Calendar 2018 その2 7日目の記事です。

## Vim の :terminal

Vim に `:terminal` 機能が入り、Vim 上からシェルを実行したり、fzf.vim のようにプラグインから `:terminal` を活用出来るようになりました。

この `:terminal` ですが、実は Vim 8.0.1685 で色設定が出来るようになりました。
[patch 8.0.1685: can't set ANSI colors of a terminal window · vim/vim@f59c6e8](https://github.com/vim/vim/commit/f59c6e8cee092433d325ba21a107654a8d84f776)

## `:terminal` の色設定の方法

patch 8.0.1685 では以下の関数とオプションが導入されており、GUI の場合か `termguicolors` が有効な場合、 `:terminal` を設定した色で表示することが出来ます。

- `term_getansicolors({buf})`
- `term_setansicolors({buf}, {colors})`
- `g:terminal_ansi_colors`

色設定は `g:terminal_ansi_colors` に16色の ANSI カラーを設定します。
（コメント部分の色説明は、iTerm 2 を参考にしています）

```vim
let g:terminal_ansi_colors = [
\ '#073642', " black
\ '#dc322f', " Red
\ '#859900', " green
\ '#b58900', " yellow
\ '#268bd2', " blue
\ '#d33682', " magenta
\ '#2aa198', " cyan
\ '#eee8d5', " white
\ '#002b36', " black (bright)
\ '#cb4b16', " red (bright)
\ '#586e75', " green (bright)
\ '#657b83', " yellow (bright)
\ '#839496', " blue (bright)
\ '#6c71c4', " magenta (bright)
\ '#93a1a1', " cyan (bright)
\ '#fdf6e3', " white (bright)
\ ]
```

## デモ

<img width="1679" alt="スクリーンショット 2018-12-07 10.19.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/31403/00e5d844-125e-d094-4af7-603b246e654d.png">

色表示には http://yonchu.hatenablog.com/entry/2012/10/20/044603 に記載の `color16.sh` を利用させていただきました。
Vue.js Unknown custom element の原因と対策　コンポーネントを登録　命名ケースに注意

Vue.js勉強中

# Vue.js Unknown custom element の原因と対策

```
Unknown custom element: <＊＊＊＊> - did you register the component correctly? For recursive components, make sure to provide the “name” option.
```
って出るやつ
とある既存のソースを参考にしてハローワールドをいじっていたらわけわかんなくなった話。
正しくコンポーネントを登録できていないらしい

# コンポーネント登録のやり方
公式ドキュメントをみる
https://jp.vuejs.org/v2/guide/components-registration.html
引用
>
>コンポーネント名を定義する時、2 つの選択肢があります:
>
ケバブケース (kebab-case)
>Vue.component('my-component-name', { /* ... */ })
>ケバブケースでコンポーネント名を定義する場合、そのカスタム要素を参照する時も同様に、 <my-component-name> のように、ケバブケースを用いなければいけません。
>
>パスカルケース (PascalCase)
>Vue.component('MyComponentName', { /* ... */ })
>パスカルケースでコンポーネントを定義する場合、そのカスタム要素の参照には、どちらのケースも用いることができます。これは、 <my-component-name> と <MyComponentName> のどちらも許容されることを意味します。ただし、DOM 内 (すなわち、文字列でないテンプレート) に直接使用する場合には、ケバブケースの名前のみが有効なので注意してください。

まさか命名ケースによって動作が違うとは夢に思わずかなりハマりました。:head_bandage:
いつもjavascriptを扱うときは気になった変数でgrep検索をかけてどこでその変数が使われているかとかそのfunctionの定義はどこだとか調べる癖があったんですけど

上記の例でいうと
「my-component-name」という文字列で検索をかけても「MyComponentName」は出てこないわけです。
この命名ケースによる寛容な仕様を知らないとMyComponentNameで検索をかけようとは思わないんですよね・・・:cold_sweat:

既存のソースを読んでいて「my-component-name」はどこで定義されるのかわからず悩みました。
Monacaを使ってメモ帳を作る

私はMonacaの勉強を始めたばかりの学生ですが、はじめてメモ帳アプリを作ってみました。
私が授業で習ったことなどを書いていこうと思います。

～メモ帳の画面～
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/320479/0f2ba96f-2528-caa5-281f-bf6eed29f577.png)

とてもシンプルなものですが、「保存する」を押すとlocalStorageに保存されるのでスマホを再起動してもデータが残ります。「削除する」を押すと削除されるというものです。

～ソースコード～

ソースコードは以下の通りです。画面はOnsen UIを使って実装しています。

    <!DOCTYPE HTML>
   
	<html lang="ja">
    <head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, 
    maximum-scale=1, user-scalable=no">
	<meta http-equiv="Content-Security-Policy" content="default-src * data: 
    gap: content: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src 
    * 'unsafe-inline' 'unsafe-eval'">
	<script src="components/loader.js"></script>
	<link rel="stylesheet" href="components/loader.css">
	<link rel="stylesheet" href="css/style.css">
	<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
	<title>HTML5を使ったメモ帳</title>

	<script>
      function savetext(){
        var savedate = document.getElementById('memo').value;
        localStorage.setItem('memo', savedate);
        return false;
      }

      function deletetext(){
        localStorage.clear();
        document.getElementById('memo').value= "";
        return false;
      }
	</script>

    </head>

    <body>
	<div class="toolbar">
	<div class="toolbar__center">メモ帳</div>
	</div>
	<textarea id="memo" class="textarea textarea--transparent" rows="10" cols="40" placeholder="Textarea"></textarea>

	<div>
	<button class="button button--outline" onclick="savetext()">保存する</button>
	<button class="button button--outline" onclick="deletetext()">削除する</button>

	</div>
	<script>
	var memo = localStorage.getItem('memo');
    console.log(memo);
    document.getElementById('memo').value = memo;
	</script>

	
    </body>
    </html>

～ソースコード解説～

要点にまとめて解説していきたいと思います。

![キャプチ.PNG](https://qiita-image-store.s3.amazonaws.com/0/320479/4b61bc49-17ab-3eda-c970-fe40a95a0bc4.png)

メモ帳のツールバーにはこのようなコードを使いました。

    <div class="toolbar">
    <div class="toolbar__center">メモ帳</div>
    </div>


 ![キャチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/320479/a540ecb8-7233-e0dc-8edd-d30228cbf210.png)

テキストエリアにはこのようなコードを使いました。

     <textarea  id="memo" class="textarea textarea--transparent" rows="10" 
     cols="40"placeholder="Textarea"></textarea>


![プチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/320479/8055d332-5576-95e2-2e21-3c4fe352de96.png)

保存・削除のボタンにはこのようなコードを使いました。

    <div>      
    <button class="button button--outline" onclick="savetext()">保存する 
    </button>
    <button class="button button--outline" onclick="deletetext()">削除する       
    </button>        
    </div>



保存と削除の関数はこのようなものを使いました。

 
      function savetext(){
        var savedate = document.getElementById('memo').value;
        localStorage.setItem('memo', savedate);
        return false;
      }

      function deletetext(){
        localStorage.clear();
        document.getElementById('memo').value= "";
        return false;
      }       
     
　　　 　　 　　　　
～おわりに～

今回は作ったのはメモ帳というシンプルなものでしたが、これからもっと難しいものを作れるように勉強を頑張っていきたいです。
【Sharepoint 2013】Sharepoint で使える javaScript メソッド 

## 使い所
　**スクリプト エディター Webパーツ** 等に記述するスクリプトに使えます。

## .format
元々 **JavaScript** には日付のフォーマット処理を行うための標準の関数やメソッドがないので、便利です。

```js
    // 文字列の書式設定
    var text = String.format('{0}\n{1}', dateStr, item.OData__ModerationComments); 

    // Date 型の書式設定
    var modified = new Date(item.Modified); 
    var dateStr = modified.format('yyyy/MM/dd(ddd) hh:mm:ss'); 
```
flexboxを用途ごとにはいぱーざっくり理解する

どうも、はぐっです・ω・♪
## はじめに
「display flex」
「flexbox 使い方」
もうこんな検索かけたら、えぐいぐらいの数の記事が引っかかるかと思います。
なので、よく書いてあることはだいぶざっくりめに進めていきます。

私はもともとwebのフロントエンドエンジニアだったのですが、現在はiOSエンジニアとして働いています。
そのため、webを書く機会は減っていたのですが、この間久々にしっかりしたwebサイトをコーディングする機会があり、
**flex使ってみよー・ω・♪**
って感じで使ってみたら案外というかすげぇいい感じだったので、記事にしようと決意の朝に。

## flexboxって？
今まで面倒だったレイアウトたちの攻撃力をほぼ0にしてくれる、
(ドラゴンクエストライバルズでいうと**アンルシア**のような)
優秀なレイアウトの組み方。
比較的新しいものなので、古いブラウザに対応しないといけないあなたは・・・

みんな仲良し**Can I use！**
[https://caniuse.com/#search=flex](https://caniuse.com/#search=flex)

新しいIEだからといって油断しないで。
ちょいちょい予想外に崩れる。

## 従来の並べ方
今までは、floatを使って要素を並べることが多かったかと。

親::after (clearfixのやり方は各自好きなように)

```css

clear: both;
content: '';
display: block;
```

子

```css
float: left;
```

まぁ、悪くはない。
悪くはないけど、レイアウトが複雑になるにつれて構造もコードもぐちゃってくる。

例えば、
高さが可変のアイテムを横並びさせたときに発狂したくなる。

こういうのも、簡単にできちゃうんですよ
そう、flexboxならね。

## flexboxの使い方
がちゃがちゃ書くのは他の記事に任せて、
本当にかいつまんで、いきます。

### 基本
```css
display: flex;
```
これで、flexboxが使えるように！
以降、このコードは入ってるものとして進めていく。

### 左右中央寄せ
```css
justify-content: center;
```
いじょっ！
これだけで左右中央寄せに！

### 上下中央寄せ
```css
align-items: center;
```
いじょっ！
これだけで上下中央寄せに！

とまぁ、この辺りまではよくあるよねって話なのだが、もはやこの時点で素晴らしい。
cssが魅せたドラマに乾杯。

で、続くと、

### 一行に入りきらんくなったら回り込んでほしい
```css
flex-wrap: wrap;
```
いじょっ！
これで入りきらんくなったら要素が回り込んでくれるように！
floatで横並んでると勝手になってくれるから、今までfloat使ってた人は勝手がちょっと違うかも。

### 縦に並べたい
```css
flex-direction: column;
```
いじょっ！
これで縦に並ぶように！

### 並び順を指定したい
ここだけ、一旦基本のやつ忘れてください。
親子関係で書くゆえに。

親

```css
display: flex;
```

子

```css
order: 1;
```
いじょっ！
これでhtml内の記述と、表示される順番を変えられるように！
orderが1の要素から順に表示されることとなる。

使うまでは、 
そんなことある？
って思ってたけど、まさかの使うタイミングが出てきて、使ったら便利すぎて泣きそうになった。

想定される使い方としては、レスポンシブサイトで

* PCでは横に三つ要素を並べたい
* SPでは縦に並べて、かつ横並びの時には中心にあった要素を一番上に並べたい

といった場合！
図にするとこんな感じ
![](https://qiita-image-store.s3.amazonaws.com/0/81434/550245fd-7813-7f89-d9ce-653a3cee86f3.png)
![](https://qiita-image-store.s3.amazonaws.com/0/81434/6dfa1a0d-8575-956e-59b7-894e9c9f4436.png)

レスポンシブやからこそ、使う機会が増えている、そんなものかなと。

## 古いブラウザ対応
まぁ、控えめに言っても無視。
とかできない場合は、今まで通りfloatとかを駆使していくしかねぇ、前しか向かねえ。

## おわりに
html,css界隈はちょいちょい素晴らしいものができていってるイメージ。
**object-fit**とかも感動的やったなー。

便利なものは使っていきたい(古いブラウザには**メッセヨ**を放ちたい)

精神衛生には気をつけて、良きコーディングライフを！

さらばっ・ω・♪
AWS Lambda でGoを動かしてみる

![1.png](https://qiita-image-store.s3.amazonaws.com/0/94929/785a0c66-81b0-edd2-c813-2d8a3a550a91.png)

ランタイムに`Go`を選択します。

そしたらLambdaにデプロイするコードを書きます。
Lambdaのライブラリが必要なので`go get`で取得しましょう。

```sh
$ go get github.com/aws/aws-lambda-go/lambda
```

以下が実行するコードです。エンドポイントにアクセスすると`"Hello"`とだけ返します。

```golang
package main

import (
  "fmt"
  "context"
  "github.com/aws/aws-lambda-go/lambda"
)

func HandleRequest(ctx context.Context) (string, error) {
	return fmt.Sprintf("Hello!"), nil
}

func main() {
  lambda.Start(HandleRequest)
}
```

コードを書いたら実行ファイルを作成しましょう。
`go build`でコンパイルするのですが、Linux向けでないといけないので、`GOOS`を指定します。
Lambdaにアップロードするにはzipにまとめる必要があるので、コンパイルできたらzipします。

```sh
$ env GOOS=linux go build -o hello
$ zip handler.zip ./hello
```

![2.png](https://qiita-image-store.s3.amazonaws.com/0/94929/c206805b-2721-a82e-6bf6-5d602a910eb6.png)

zipができたらLambdaの管理画面からアップロードを押して実行ファイルをデプロイしましょう。

# 結果を確認

では正しく結果が返ってくるのをテストしてみましょう。
管理画面のテストボタンを押してテストイベントを作ります。
実行する関数に引数は無いので、jsonは適当に書いておいてテストを作成します。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/94929/3fbe8efe-cfa2-8cda-2903-c62e3bfec809.png)

作成できたら管理画面でテストボタンをクリックすると、実行結果が表示されるので確認してみましょう。
`"Hello"`と出てたらOKです。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/94929/9bec1cb1-7c2f-58dc-7604-c518502b9f2c.png)
軽量ORMのidiormで調べた事まとめ

仕事で、軽量ORMのidiormを使っていて、
こちらの素晴らしい記事をいつも参考にさせていただいております。

[PHPの薄いDBライブラリ「Idiorm」を使ってみた](https://qiita.com/naga3/items/87fef230ac86aeec1eea)
[PHPでORM「idiorm」を使えばかんたんにDBを操作できる](https://qiita.com/iritec/items/5342a8b6031c982c85c4)

ただ、公式ドキュメントなどを調べないとわかない事などもあったため、
調べた内容をまとめておきたいと思います。

###where in
```php
<?php
$param = ['山田', '田中', '鈴木'];
$people = ORM::for_table('person')->where_in('name', $param)->find_many();

//実行されるSQL
SELECT * FROM `person` WHERE 'name' IN ('山田', '田中', '鈴木');
```

###where like
```php
<?php
$people = ORM::for_table('person')->where_like('name', '%山田%')->find_many();

//実行されるSQL
SELECT * FROM `person` where 'name' like ('%山田%');
```

###MIN、MAX、SUM、AVG、COUNTなどの関数の利用
```php
<?php
$count = ORM::for_table('person')->min("age");

//実行されるSQL
SELECT MIN(age) AS 'min' FROM `person` LIMIT 1;
```
同じ要領でMIN、、MAX、SUM、AVGも取得できます。

###OFFSET、LIMIT
```php
<?php
$count = ORM::for_table('person')->offset(2)->limit(3)->find_many();

//実行されるSQL
SELECT * FROM `person` LIMIT 3 OFFSET 2;
```

###関数による値の更新
```php
<?php
$person = ORM::for_table('person')->findOne(1);
$person->set_expr('up_date', 'NOW()');
$person->save();

//実行されるSQL
UPDATE `person` SET 'up_date' = NOW() WHERE `id` = 1;
```

###関数による値の並び替え
```php
<?php
$people = ORM::for_table('person')->order_by_expr('LENGTH(`name`)')->find_many();

//実行されるSQL
SELECT * FROM `person` ORDER BY LENGTH(`name`)
```

###idiormで実行したSQLログの確認
```php
<?php
ORM::configure('logging', true);
$sqls = ORM::get_query_log() ;
var_dump($sqls);
```


###まとめ

idiormに慣れるととっても楽です！
でもSQLが書けなくなりそう💦
背景色うねうねcss+javascript

背景色をうねうねさせたいときってありますよね。
そんなときにご利用ください。


<p data-height="265" data-theme-id="0" data-slug-hash="PxMyaO" data-default-tab="js,result" data-user="prexlab" data-pen-title="PxMyaO" class="codepen">See the Pen <a href="https://codepen.io/prexlab/pen/PxMyaO/">PxMyaO</a> by prexlab (<a href="https://codepen.io/prexlab">@prexlab</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>