OmniAICreator/Qiita-1.07M huggingface dataset:
useEffectでsetTimeoutの繰り返しを使う場合はuseEffectに任せて再帰呼び出しはしない

例えば現在の時刻をリアルタイムに表示させたい場合、カスタムフック `useWatch` を作って、そこから更新され続ける `time` を受け取りたい。

```tsx
const App: React.FC = () => {
	const time = useWatch(1000);
	return <span>{dayjs(time).format('HH:mm')}</span>
};
```

## 結論

```ts:use-watch.ts
import { useEffect, useState } from 'react';

export default function useWatch(interval: number) {
	const [time, updateTime] = useState(Date.now());

	useEffect(() => {
		const timeoutId: number = setTimeout(() => updateTime(Date.now()), interval);
		return () => {
			clearTimeout(timeoutId);
		};
	}, [time]); // eslint-disable-line react-hooks/exhaustive-deps

	return time;
}
```

1. `useEffect` のコールバックが実行開始。
2. `interval` ミリ秒後に `updateTime` されて `time` が更新される。
3. **`time` が更新されたので `useEffect` が反応**。
4. クリーンアップがあるため、クリーンアップを実行。 `clearTimeout` される。
5. **1〜4 を繰り返す**。
6. 利用しているコンポーネントがアンマウントされたときに、クリーンアップを実行。 `clearTimeout` される。

結論は、 `useEffect` のコールバックが繰り返し実行されるので**再帰呼び出しは不要**。

## 間違った実装

```ts
import { useEffect, useState } from 'react';

export default function useWatch(interval: number) {
	const [time, updateTime] = useState(Date.now());
	const update = () => {
		updateTime(Date.now());
		const id = setTimeout(update, interval);
		return () => {
			clearTimeout(id);
		};
	};

	useEffect(update, []);

	return time;
}
```

`update` 関数を作って `setTimeout` で再帰呼び出しを行っているので、 `time` は問題なく一見うまくいっているように見える。
しかし、 コンポーネントのアンマウントによってクリーンアップがされた場合、クリーンアップ関数のスコープの `id` は初回の値で固定されているため、ただしく `clearTimeout` ができなくなる。
クリーンアップ関数のスコープの `id` を随時更新するには `useEffect` の依存変数を調整することになるが、その時点で `useEffect` のコールバックが繰り返し呼び出されることになるので、先の結論の実装に落ち着く。
SwiftEnrtyKitでcustomViewも手軽にポップアップ表示

##使用するライブラリ
swiftEntryKit
https://github.com/huri000/SwiftEntryKit

##注意するところ
自作のビュー/ビューコントローラーをpopupさせたい時、
width,heightについてconstraintをつけないと表示されないので気をつけてください。

```swift
//ダメな具体例
let customView = UIView(frame: CGRect(x: 0, y: 0 , width: 300, height: 200))

//修正するとこうなる
let customView = UIView()
let widthConstraint = customView.widthAnchor.constraint(equalToConstant: 300)
widthConstraint.isActive = true
let heightConstraint = customView.heightAnchor.constraint(equalToConstant: 200)
heightConstraint.isActive = true
```

##実際の関数

```swift
    private func showPopUp(){
        var attributes = EKAttributes.centerFloat
        attributes.position = .center
        attributes.displayDuration = .infinity
        attributes.entryBackground = .color(color: .white)
        attributes.entranceAnimation = .none
        attributes.exitAnimation = .translation
        attributes.screenInteraction = .dismiss

        let customView = UIView(frame: CGRect(x: 0, y: 0 , width: 300, height: 200))
        let widthConstraint = customView.widthAnchor.constraint(equalToConstant: 100)
        widthConstraint.isActive = true
        let heightConstraint = customView.heightAnchor.constraint(equalToConstant: 300)
        heightConstraint.isActive = true
        customView.backgroundColor = .orange
        SwiftEntryKit.display(entry: customView, using: attributes)
    }
```

呼び出したい箇所で self.showPopUP()で表示されます
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273734/5b91f6d7-df66-7d49-ce12-d2082da52269.gif)


##参考文献
https://github.com/huri000/SwiftEntryKit/issues/165
Firestore.Timestamp に触れたくないあなたのための黒魔術

# Firestore.Timestamp って、いらなくね？

ちゃんと使いこなせばメリットもあるんだろうなぁと思いつつ・・・
少なくとも小規模なプロジェクトでは、Timestamp型が存在するせいで

- Firestore から読んだ、時刻フィールドを toDate() で Date型にもどす
- Document の interface と、 REST をまたぐ interface を分ける

みたいな対応が必要になるわけです。いちいちめんどいんすこれ。
Date 型で十分な状況もあるんです。

## 問題の例
```ts
interface User {
  name: string;
  updatedAt: Date;
}

const write: User = {
  name: "taro",
  updatedAt: Date.now(),
};
await firestore
  .collection("users")
  .doc(write.name)
  .set(write);

const read: User = 
  await firestore
    .collection("users")
    .doc(write.name)
    .get()
    .then(dss=>dss.data());

console.log(read); // updatedAt が Timestamp クラスになってるよ！
```

## 魔術の源: Timestamp を Date へ再帰的に変換するヘルパーメソッド
```ts
function timestampToDateRecursively(value: any): any{
  if (value == null) {
    return value;
  } else if (value.constructor === Firestore.Timestamp) {
    return value.toDate();
  } else if (Array.isArray(value)) {
    return value.map(timestampToDateRecursively);
  } else if (value.constructor === Object) {
    const converted: any = {};
    for (const key in value) {
      converted[key] = timestampToDateRecursively(value[key]);
    }
    return converted;
  } else {
    return value;
  }
}
```

## 白魔術: いちいちヘルパーメソッドをかませる

- どこで何が起きてるかわすりやすい。安全。
- いちいち忘れたりする。めんどい。

```ts
const read: User = 
  await firestore
    .collection("users")
    .doc(write.name)
    .get()
    .then(dss=>timestampToDateRecursively(dss.data())); // 毎回書く必要あり 

console.log(read); // updatedAt がちゃんと Date になってるね
```


## 黒魔術: DocumentSnapshot.data() をオーバーライドする

- 意識しなくても勝手に変換されてる。便利。
- 知らないと、Firestoreの仕様の誤解や混乱のもとになる。危険。

```ts
/**
 * DocumentSnapShot.data() で返すすべてのTimestamp型をあらかじめDate型へ変換するよう
 * プロトタイプをオーバーライドします
 */
function wrapDocumentSnapshotData() {
  console.log(`Wrapping DocumentSnapshot.data()`);
  const origin = Firestore.DocumentSnapshot.prototype.data;
  Firestore.DocumentSnapshot.prototype.data = function () {
    const data = origin.bind(this)();
    const converted = timestampToDateRecursively(data); // ここ！
    return converted;
  };
}

wrapDocumentSnapshotData();

const read: User = 
  await firestore
    .collection("users")
    .doc(write.name)
    .get()
    .then(dss=>dss.data()); // いちいち意識しなくていい

console.log(read); // updatedAt がちゃんと Date になってるね
```
WordPressで広告測定の成果地点を計測するために、meta refreshを管理する方法

## 背景

- コンバージョンページを設定して、広告測定のためにScriptを発火させたい
- コンバージョンページは、meta freshを利用したリダイレクトを行いたい


## 課題

- 現状は301リダイレクトで、HTMLが読み込まれないため発火できない
- 301リダイレクトの管理ツールは多くあるが、meta freshリダイレクトをページごとに管理するツールが存在しない
    - redirection というプラグインは一般的だが、meta refreshでは存在しなかった

## 打開策

- ページごとにmeta tagを編集できるプラグインMeta Tag Managerがあったので、特定のページにmetaタグを仕込んで、ページ管理することで解決

https://ja.wordpress.org/plugins/meta-tag-manager/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134704/8d34e413-129c-4610-b752-bef44e749fd4.png)


- 実際のコンバージョンタグは、タグマネから管理するのがよさげ。
MySQL5.7での初期ユーザー設定


忘れるのでメモ
ルートパスワードを好きなものに変更するバッチ。
パスワードの強度は最低にする。root/rootでもOK。なので、使用は注意。

```
#!/bin/bash

MYROOTPASSWORD='password'

DEFAULT_PASSWORD=`cat /var/log/mysqld.log | grep "temporary password" | awk '{print $11}'`
mysql -u root -p${DEFAULT_PASSWORD} --connect-expired-password -e "SET GLOBAL validate_password_length=4;"
mysql -u root -p${DEFAULT_PASSWORD} --connect-expired-password -e "SET GLOBAL validate_password_policy=LOW;"
mysql -u root -p${DEFAULT_PASSWORD} --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYROOTPASSWORD}';"
```

サブアカウントを作るバッチ。

```
#!/bin/bash
MYROOTPASSWORD='password'
MYSECONDUSER='root2'
MYSECONDPASSWORD='password2'

mysql -u root -p${MYROOTPASSWORD} -e "SET GLOBAL validate_password_length=4;"
mysql -u root -p${MYROOTPASSWORD} -e "SET GLOBAL validate_password_policy=LOW;"
mysql -u root -p${MYROOTPASSWORD} -e "create user ${MYSECONDUSER}@localhost identified by '${MYSECONDPASSWORD}';"
mysql -u root -p${MYROOTPASSWORD} -e "grant all on *.* to ${MYSECONDUSER}@localhost identified by '${MYSECONDPASSWORD}';"
mysql -u root -p${MYROOTPASSWORD} -e "grant all on *.* to ${MYSECONDUSER}@'%' identified by '${MYSECONDPASSWORD}';"
mysql -u root -p${MYROOTPASSWORD} -e "flush PRIVILEGES;"
```
GitHubのPRコメントの中でissue検索を簡単にできるぞ

表題の通りの小ネタです。

以前 [issueを自動クローズする方法についての記事](https://qiita.com/yamotuki/items/3882a9943cec27e0e8f4)を書きました。
前回の記事を書いた時には `close: https://github.com/aaa/iiii/issues/411` のようにリンクを貼り付けるかissue番号を書かないとダメでした。

しかしいつの間にかタイトルで検索できるようになっていましたのでその共有です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/bfbfe24c-7f97-14b1-7d7f-7ebc78b92340.png)

`!`がついているものがissueのようです。それ以外はプルリクエスト。


issue閉じ忘れ、後から 「これ終わっているの？」 と確認して閉じていくの地味に面倒なのでみんなこの機能使ってね！
【windows】git2.26以下の脆弱性回避

表題の件、Mac, Linuxに関しての情報はあるが、Windowsに関して見当たらなかったので記載

```console
$ git update-git-for-windows
```

上記コマンドをcmdやらpowershellやらで打つだけ。お手軽。
chocolateyがリッチになるかもっとイケてる代替パッケージ管理システムが出てくるのを期待。
Firebase functionsで 403 error "Your client does not have permission to get URL /** from this server" となった場合の解決策

久しぶりにFirebase functionsを使ってHelloWorldしようとしたら
`Your client does not have permission to get URL /helloWorld from this server`
となって、少しはまってしまったので解決方法をご紹介いたします。

![Screenshot 2020-04-22 10.17.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60143/2f6616ac-d8ed-4455-820b-3de006419449.png)

# Google Cloud Consoleで権限を付与する
2020年1月15日時点より、Cloud Functionsの関数に関して、未認証の場合はデフォルトで呼び出しできない用になっているようです。（それまでは、未認証でも関数呼び出し実行できたが今は設定しないとできない）

そこで、Google Cloud Console内で該当する関数の設定を行います。

1. [Google Cloud ConsoleのFunctionsの設定画面](https://console.cloud.google.com/functions)にログインします
    2. Firebaseでプロジェクトを作成しているのと同一のアカウントでログインします
    3. Firebaseの該当のプロジェクトを選択します。
2. アクセス権を付与する関数の横にあるチェックボックスをクリックします。
![cloudfunction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60143/d19a1663-25ed-f9ae-9bea-120857b3e924.png)

3. 右上隅にある [情報パネルを表示] をクリックして、[権限] タブを表示します。
4. [メンバーを追加] をクリックします。
5. [新しいメンバー] フィールドで、「**allUsers**」と入力します。
6. [役割を選択] プルダウン メニューから **Cloud Functions** > **Cloud Functions** 起動元 役割を選択します。
![Screenshot 2020-04-22 10.37.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60143/3374bd5d-bf61-afbe-d645-83c6f9f67523.png)

7. [保存] をクリックします。
8. FirebaseのFunctionsで該当の関数にアクセスします。（helloWorld）
![helloworld.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60143/82a16cc4-ccd9-3c99-038f-f772f8d20300.png)

表示されました！
これで完了です。

# 公式ドキュメント：
Google Cloud のドキュメントにも記載があります。
https://cloud.google.com/functions/docs/securing/managing-access-iam#allowing_unauthenticated_function_invocation

以上
Windows10のPHPビルトインサーバでwordpressをインストールし起動する

# はじめに

いつもはワードプレス案件の開発をするときにはvagrantをセットアップして、httpdとMySQLを入れてとやっていたがビルトインサーバを使えば簡単じゃねと思ってためしてみました。

# MySQLのこと忘れていない？

そうです。MySQL、必須です。ビルトインサーバには入っていません。なので今回はXAMPPに入っているMySQLを使います。
多分、単独のMySQLでも動きそうな気がしましたが未検証です。
XAMPPはZipをダウンロードして展開すればOKなので環境を汚さずにすむのがうれしいのですが、複数案件を進めているときApacheのディレクトリがカオスになるのでvagrantを使うようになりました。
ここでXAMPPが再登板させるとは。

# まずはワードプレスをダウンロード

ここから最新版をダウンロードしてすきなディレクトリに展開します。

~~~
https://ja.wordpress.org/download/
~~~


# MySQLを起動しておきます。

xamppコンパネを起動し、MySQlのスタートボタンで起動！
小心者の私は、起動しているか不安になってので

いつも使っているSQLクライアントの

~~~
[HeidiSQL]
https://www.heidisql.com/
~~~

を起動し

~~~
IP:127.0.0.1
user:root
pass:空欄
~~~

でアクセス

無事アクセス出来たのを確認し胸をなでおろしました。
ここで実際に使うデータベース「wordpress」も事前に作っておくと手間が減ってうれしい感じになります。

# いよいよワードプレスのインストール

ここでワードプレスを展開したディレクトリに移動します。
ターミナルとかGitBashとかで

~~~
php -S localhost:80
~~~

と打ってビルトインサーバを起動します。

~~~
http://localhost
~~~
へアクセスするとインストーラーが立ち上がりインストールが開始されます。
ここでデータベース名などを入力するのですが

~~~
データベース名：wordpress <= 事前に作成したもの
ユーザー名：root
パスワード：空欄に
ホスト名：localhost　
接頭辞：wp_ <=そのまま
~~~
と入力してインストールを進めます。
すこし重い気がするが待っていると、インストールが完了します。

あとは、ワードプレスの管理者ユーザ名とかサイト名とかを設定すればインストール完了！
管理者画面へ遷移するので設定したID/PWを入力すれば管理画面が表示されます。
サイトを確認のために

~~~
http://localhost
~~~

へアクセスして無事トップページが表示されればインストール作業も無事終了です。
XAMPPのMySQLを使っているということで結局XAMPPかよと思われる方もいる気がしますが環境をあまり汚さずWindows10で複数のワードプレス環境を平行して使えるというのはメリットではないかと思います。
ビルトインサーバは、起動した場所をルートとするので複数バージョンのワードプレスでの挙動確認なんかで使ってもよいのではないでしょうか。
それに環境起動時にオーバーヘッドが少ないのもうれしい感じです。
Node.js + ibm_db + Db2 で、ODBCパラメータを設定する

Node.jsのアプリケーションを実行にあたって、ODBCパラメータを設定することができます。
ODBCパラメータはdb2dsdriver.cfgファイルに設定します。

## db2dsdriver.cfg ファイルの作成
Db2 9.7 FP3 以降、db2dsdriver.cfg 構成ファイルはDb2には同梱されない代わりにサンプルファイルが同梱されるらしいです。(db2dsdriver.cfg.sample　※)
　(※)Docker版Db2には、サンプルファイルも入っていないかも？

```
<configuration>
   <dsncollection>
      <dsn alias="DB1" name="TESTDB" description="alias_db1_description" host="localhost" port="50000"/>
      </dsn>
   </dsncollection>
   <databases>
      <database name="testdb" host="localhost" port="50000">
         <parameter name="CurrentSchema" value="db2inst1"/>
         <specialregisters>
            <parameter name="CURRENT DEGREE" value="'ANY'"/>
         </specialregisters>
      </database>
   </databases>
</configuration>
```

DB2DSDRIVER_CFG_PATH レジストリー変数に、db2dsdriver.cfg のパス名＋ファイル名を指定します。

```
export DB2DSDRIVER_CFG_PATH=/work/node/db2dsdriver.cfg
```

余談：マニュアルに「DB2DSDRIVER_CFG_PATH レジストリー変数」と書かれているのでレジストリー変数なのかと思ったら、環境変数でした。db2setコマンドでは設定できません。このことにびっくり。

db2setで設定できるレジストリー変数なのかは、db2set -lr コマンドで確認。

```
db2set -lr | grep -i DB2DSDRIVER
(出力なし)
```

## サンプルコード

 - T3表のスキーマを指定せずSELECT実行する。(SELECT .. FROM T3)
 - db2dsdriver.cfg  (CurrentSchema = db2inst1) が有効であれば、db2inst1スキーマのT3表がSELECTされるはず。
 - db2dsdriver.cfg が読み込まれていない場合、user1スキーマのT3表をSELECTしようとして、そんな表はないというエラーとなる。

```javascript:settings.js
exports.host = 'localhost';
exports.port = 50000;
exports.dbname = 'TESTDB';
exports.username = 'user1';
exports.password = 'xxxxxxxx';
```

```javascript:test2.js
var ibm_db = require( 'ibm_db' );
var settings = require( './settings' );

var db_con_str =
"DRIVER={DB2}"
  +  ";DATABASE=" + settings.dbname
  + ";HOSTNAME=" + settings.host
  + ";UID=" + settings.username
  + ";PWD=" + settings.password
  + ";PORT=" + settings.port
  + ";PROTOCOL=TCPIP";

var sql_str = "select C1, C2 from T3 where C1=?";
var param1 = [1];

ibm_db.open( db_con_str, function( err, conn ){
  if( err ) return console.log( err );

  conn.query( sql_str, param1, function( err, data ){
    if( err ) console.log( err );

    console.log( data );

    conn.close( function(){
      console.log( 'done' );
    });
  });
});
```

### 実行結果
db2dsdriver.cfgに設定したとおり CurrentSchema が db2inst1 に設定され、
"select .. from T3" と書いたSQLが、"select ... from db2inst1.T3" として実行されました。

```
$ node test2.js
[
  { C1: 1, C2: 'a       ' },
  { C1: 2, C2: 'b       ' },
  { C1: 10001, C2: 'A10001  ' }
]
done
```
How to set the default record type when using ‘defaultFieldValues’ to set default values in Spring 20?

#デフォルト項目値を含むレコードの作成ページへの移動 機能でレコードタイプを設定する方法

デフォルト項目値を新規レコードに渡すカスタムボタンとリンクを作成します。
**対象:** この変更は、すべてのエディションの Lightning Experience に適用されます。この変更は、Lightning Out、Lightning コミュニティ、Salesforce モバイルアプリケーションには適用されません。

**方法:** 事前入力された項目値を含む新規レコードを開始するカスタムボタンまたはリンクを作成するには、次のサンプル数式を使用します。

```
/lightning/o/Account/new?defaultFieldValues=
    Name={!URLENCODE(Account.Name)},
    OwnerId={!Account.OwnerId},
    AccountNumber={!Account.AccountNumber},
    NumberOfEmployees=35000,
    CustomCheckbox__c={!IF(Account.SomeCheckbox__c, true, false)}
```

しかし、レコードタイプはこのパラメータとしてはデフォルト値の設定ができないようです。
解決策は「defaultFieldValues」パラメーターの外に「recordTypeId」を設定する必要があるようですね。

```
/lightning/o/<Object_Name>/new?recordtypeId=012XX00000XXXXX&
defaultFieldValues=
Field1=value_1,
Field2=value_2
```

どうやって発見したのだろう。

https://forcepanda.wordpress.com/2020/04/14/how-to-set-the-default-record-type-when-using-defaultfieldvalues-to-set-default-values-in-spring-20/

リリースノート
https://releasenotes.docs.salesforce.com/ja-jp/spring20/release-notes/rn_general_lex_navigate_to_record_dfv.htm
string型の文字検索でstring::nposに感動した小話

#はじめに
競プロのAtcoderをやったのだが、[ABC162問題A](https://atcoder.jp/contests/abc162/tasks/abc162_a)で文字検索を行う問題がでた。その際、解説者がstring::nposを使っていて少し驚嘆した。その話を短く書こうと思う。

#自分がやったこと
この問題では、3桁の値しか入力制約ないため、文字列で入力し論理演算子で各文字に7が含まれるか判断した。

~~~c++
    string s;
    cin>>s;
    if(s[0]=='7'||s[1]=='7'||s[2]=='2') cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
~~~
ただ、もっと簡単に表せられる方法があった。それがstring::nposである。

#string::nposとは?
[公式リファレンス](https://ja.cppreference.com/w/cpp/string/basic_string/npos)では、以下のように書かれている。
> これは size_type 型で表現可能な最大値と等しい特別な値です。 正確な意味は文脈によりますが、一般的には文字列のインデックスを期待する関数で文字列の終端として使用されたり、文字列のインデックスを返す関数でエラーインジケータとして使用されたりします。
>

要は、検索文字が見つからなかったらstring::nposを返すとのこと。
この方法で記述したのが以下である。

~~~c++
   if(s.find('7') !=string::npos) cout<<"Yes"<<endl;
   else cout<<"No"<<endl;
~~~

大分、すっきりした印象ではないだろうか
なお、findメソッドは検索文字が見つからない場合、-1を返すため、以下のように変更しても問題なく動く。

~~~c++
    if(s.find('7')!=-1)cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
~~~

#最後に
分かっている人はこんなの当たり前の知識だろと思うかもしれないが、知った時は普通にこんな短文で済むのかと感動したので...
まだまだ勉強不足ですね
swift ,バイナリファイルを読み込み,Data型を[UInt8]や[Int16]に変換

Data型->[UInt8]

```
    func ReadBinaryFile_Int8(path : String) -> [UInt8]{
        let dataURL = URL(fileURLWithPath: path)
        var binaryData = Data();
        do {
            // ファイル読み込み
            binaryData = try Data(contentsOf: dataURL, options: [])

        } catch {
            print("Failed to read the file.")
        }
        //return binaryData.encodedHexadecimals!;
        return [UInt8](binaryData)
    }
```

Data型->[Int16]

```
    func ReadBinaryFile_Int16(path : String) -> [Int16]{
        let dataURL = URL(fileURLWithPath: path)
        var binaryData = Data();
        do {
            binaryData = try Data(contentsOf: dataURL, options: [])
           
        } catch {
            print("Failed to read the file.")
        }
        
        let i16array = binaryData.withUnsafeBytes{UnsafeBufferPointer<Int16>(start: $0, count: binaryData.count/2).map(Int16.init(bigEndian:))}
        
        return i16array;
    }
```
【ふくだ学習録】サブスクリプション part2【43日目】

# ふくだ学習録とは？
ふくだが学習したことの備忘録。
目に見える形で残すことによってやる気を出す個人的な作戦です。
他人に見せるように書いているわけではないので、すごく読みにくいです。

### 読了した本
[データベースエンジニア養成読本 [DBを自由自在に活用するための知識とノウハウ満載!]](https://www.amazon.co.jp/dp/4774158062/ref=cm_sw_r_tw_dp_U_x_FPphEbQFPPQRM )
[ゼロから作るDeepLearning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_U_x_y3UiEbF3P6EG7)
[PHPフレームワーク CakePHP 3入門](https://www.amazon.co.jp/dp/4798048577/ref=cm_sw_r_tw_dp_U_x_.YIjEbS1K4JY2)
[SQLアンチパターン](https://www.amazon.co.jp/dp/4873115892/ref=cm_sw_r_tw_dp_U_x_XlokEbJQK2N7P )
[Docker入門](https://www.amazon.co.jp/dp/480071091X/ref=cm_sw_r_tw_dp_U_x_xVlmEbN8ZTHZK)
[PHPフレームワーク Laravel入門](https://www.amazon.co.jp/dp/4798052582/ref=cm_sw_r_tw_dp_U_x_zzeyEbJBSQ5Y0 )


### 今読んでいる本

[サブスクリプション](https://www.amazon.co.jp/dp/B07HY1TND9/ref=cm_sw_r_tw_dp_U_x_lp4NEb3EEGD7Y)

### サブスクリプションがきている理由
①企業価値を高く評価してくれるようになる。
→今までの売り切り型のビジネスモデルであれば、来期の売り上げは、０→１で積立が必要。
　そのため来期予測が難しく、企業価値は高くなりにくい（特に株式市場では評価されにくい）
　サブスクリプションモデルにより、年間定期収益（ARR）を高めることによって、企業価値をあげることができる。

②顧客を知ることができる
→製品を売り切るビジネスであれば、顧客が何を考えて何を真に求めているのかを把握することが難しくなる。
サブスク方式でのビジネスモデル（サービスを売る）にすることで、顧客とつながりを持つことができ、顧客理解をすることができる。

### ８章 所有から利用へ
2020年までに世界の大手企業の50%が、事業の多くをでデジタルを絡めて、サービスや経験を売っていくビジネスになっていく（製品ベースではなく、サービスベースになっていく）

#### ヘルスケア業界
アメリカのドラッグストアチェーンのCVSファーマシーは、アマゾンを恐れて、健康保険会社（エトナ）を買収した。
この買収の目的は、CVSが自社で運営する薬局で初期診療サービスを提供できるようになること。

現在のアメリカでは、患者が医者に行くと、病院に行ったり、薬局に行ったり、保険会社に行ったり、それを繰り返したりと、様々な場所に行くことになるため、情報が散らばって存在することになる。
ファーマシーはエトナを買収することで、一連の医療行為の初期段階から顧客と関わることができるようになるため、顧客理解を深め、より良いサービスを提供できるようになる。

#### 政府・自治体機関
オーストラリアのニューサウスウェールズ州の住民はIDを付与されており、そのID経由で８００以上の行政手続きやサービスを利用できる。
また相談員が駐在しているため、顧客ニーズを簡単に取得することができるようになっている。

政府支出は世界各国でGDPのかなりの割合を占めている。例えばアメリカでは約1/3。
政府・自治体機関はわりと狙い目。

#### 教育業界
現在の社会では継続的な学習が求められるのに、高等学校やビジネススクールは、数年の期間がすぎてしまうと契約を解除してしまう。そうではなく、卒業,修了がないスクールが求められていく。（例えばUdemyなど）

オンラインサロンとかもそうかも。

#### 保険業界
現在の保険料のほとんどは、本人にはコントロールできないあらゆる種類の保険数理的要因によって決定されている。
ヘルスIQは、健康に関する問診によって、活動的な生活をしている人の健康保険料を引き下げている。
今後保険会社は、デロイトが「フレキシブル・コンサンプション」モデルと呼ぶ使用料ベースの課金方式を利用していき、集団としての契約加入者ではなく、個人としての加入者に注意を向けるようになる。

# 今日の一言
各業界色々あるねんなぁ。おもろし。
RDSを開発用に作る時の備忘録

## 概要
開発用にRDSを立てて、そこにデータを流し込んだりクエリを投げたりすることもあると思いますが、
触る頻度が度々しかないと毎回基本的なことを忘れてはまってしまうので、個人的に気をつけることを備忘録としてまとめます。
随時更新していきます。


## 気をつけること

- public accessility のON OFFに注意

これがマネジメントコンソールからのRDS作成では、タブの下に隠れていて、デフォルトが OFF担っていました。
これがOFFだと、セキュリティグループできちんとコネクション元を許可していてもコネクション確立できないので、注意。

作成時の、**Connectivity** にある　**Additional connectivity configuration** をクリックすると出てきます。


中にあります。
<img width="772" alt="Screen Shot 2020-04-22 at 9.42.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/89de6571-1ed7-7f12-f0a0-00bca15bdfb4.png">

もちろん後からでもModifyから変更できる。



適宜更新中。


おわり。
僕のDAOパターン(Java)

自分用の備忘録
次の案件で使う可能性があるので、

**この記事で扱うDAOパターンの記述は、データベース接続と全件検索を行う課程のみ。DBはH2**


```java
//ライブラリインストール
import java.sql.Connection;
import java.sql.DriverManger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DAOSample{
    public static void main(String[] args){
        Connection conn = null;
        try{
            //JDBCドライバー読み込み
            Class.forName("org.h2.Driver");
            //データベースへの接続
            conn = DriverManager.getConnection("jdbc:h2:file:C:/data/DAOSample","username","password");

            //SQL準備
            String sql = "SELECT * FROM DAOSample"
            //文字のSQLをDBで使用できる型に変換
            PreparedStatement ps = conn.preparedStatement(sql);

            //SQLを実行してデータセットを取得
            ResultSet rs = ps.executeQuery();
            //取得された内容をループさせて表示
            while(rs.next()){
                String id = rs.getString("ID");
                String name = rs.getString("NAME")
                int age = rs.getString("AGE")

                System.out.println("ID:" + id);
                System.out.println("名前:" + name);
                System.out.println("年齢:" + age);
            }
        //例外処理
        }catch(SQLException e){
            e.printStackTrace();
        }catch(ClassNotFoundException e){
            e.printStackTrace();
        }finally{
            //データベース切断
            if(conn != null){
                try{
                    conn.close();
                }catch(SQLException e){
                    e.printStarckTrace();
                }
        }
    }
}

```
amazon linux swapの追加

1. swap用のファイルの作成
`sudo /bin/dd if=/dev/zero of=/var/swapfile bs=1M count=1024`

2. swap用ファイルをswap領域にセット
`sudo chmod 0600 /var/swapfile`
`sudo /sbin/mkswap /var/swapfile`

3. swap領域を有効化
`sudo /sbin/swapon /var/swapfile`

4. OS起動時にswap領域をアクティブにする
`sudo vim /etc/fstab`

以下を追加

```bash:/etc/fstab
/var/swapfile swap swap defaults 0 0
```
JSONのまとめ（メモ用）

自分のメモ用に、学んだことを書きます。
業務でAPIを触る機会があり、「JSONは知っているか？なにかと使うだろうから覚えておくといい」という話をされたので、復習も兼ねてJSONについてまとめていきます。
※まだメモ用程度なので、今後も追記していく予定です。

#JSONとは
JSONとは「JavaScript Object Notation」の略で、データをやりとりする形式の一種。
もともとはJavaScriptと他の言語をやりとりをするために考えられた、オブジェクトを表記するための書き方の決まりごとである。
ファイルの中身はただのテキストデータなので人間が見ても内容を理解することができる。ファイルの拡張子は."json"。
下記は東京タワーの住所を表しているJSONファイルである。

`````zipcode.json
		{
			"address1": "東京都",
			"address2": "港区",
			"address3": "芝公園",
			"kana1": "ﾄｳｷｮｳﾄ",
			"kana2": "ﾐﾅﾄｸ",
			"kana3": "ｼﾊﾞｺｳｴﾝ",
			"prefcode": "13",
			"zipcode": "1050011"
		}
`````

##JSONの構造をみていく
JSONは右と左に文字があり、真ん中が：（コロン）で区切られている。
左辺は「メンバー」と呼ばれ、文字列の値で書かれている。
右辺は「値」と呼ばれ、全部で6種類存在する。

まずは右辺の説明から。
>文字列値(string)："abc"や"def"等、任意の情報をダブルクオートで囲んだ記述。
数値(number)：1や23.45等、数値をそのまま書いた記述。
真偽値(boolean)：true及びfalseという「yes/no的な意味合い」を表現する特別な記述。
ヌル値(null)：nullという「値がカラッポであること」を表現する特別な記述。
配列値(array)：[]や[1]や[1,true]等、0〜複数個の値の並びを表現する記述。
オブジェクト値(object)：{}や{"foo":"bar"}や{"foo":"bar", "baz":null}。
※一方、下記は「値」ではありません。
abcやd"ef"や"ab（全体がクオートされていなかったり閉じていない。）
TRUEやNULL（大文字と小文字は区別する。）
[1][2,3]や[1],[2,3]や{}{}（複数の値がつながったものは値ではない。）

次に左辺について。
>"foo": "hoge"
"bar":"fuga"
"baz":1
"qux":[]
※一方、下記は「メンバー」ではありません。
1:2（左辺が文字列値じゃない。）
"foo";"bar"や"foo"や1（コロンがない。）
"foo":"bar":"baz"（コロンが2つ以上ある。）
"foo":hoge（右辺が値じゃない。）
[【非エンジニアに贈る「具体例でさらっと学ぶJSON」】より抜粋](https://dev.classmethod.jp/articles/concrete-example-of-json/)

#なぜJSONが通信用のデータ交換として利用されているのか
テキストデータであるJSONは軽量かつオブジェクト構造になっている。
このことから、これまで使われていた冗長なXMLデータに比べて通信時のデータ量を削減することができる。
また、構造をみてわかるとおり、JSONは配列値からオブジェクトまで幅広く取り扱うことができる。このことから、複雑なデータもJSONでは取り扱うことができるとわかる。

#引用元
https://dev.classmethod.jp/articles/concrete-example-of-json/
Twitterカードの設定をしてみた


[【2020年版】Twitterカードとは？使い方と設定方法まとめ](https://saruwakakun.com/html-css/reference/twitter-card)

上記の『3. Twitterカードの使い方』を真似ってやってみた

ただしく表示されることを確認した

```html

    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@xxxxx"/>
    <meta property="og:url" content="https://sisterroom-ed073.firebaseapp.com/" />
    <meta property="og:title" content="あやりちゃんのお世話になっているルームのイベント情報" /> 
    <meta property="og:description" content="おせわなっているルームの現在進行中イベント情報です" /> 
    <meta property="og:image" content="https://sisterroom-ed073.firebaseapp.com/img/ayari_room_img.jpg" />
```
yarn start 時にブラウザを起動させない

### やること🌵
`yarn start` または `npm satrt` するときにブラウザを起動させないようにする


### 方法A
`package.json`で起動時に環境変数を渡すよう記述

```package.json
"scripts": { "start": "BROWSER=none react-scripts start" }
```

### 方法B
`.env` ファイルをプロジェクトルートに作成し環境変数を渡す

```/.env
BROWSER=none
```
※ただし、`zsh` で `Prezto` などを導入している場合 `~/.zprofile` に`BROWSER="open"`で上書きされる記述があるため方法Bは使えない
Twitter Web Intentで、URLの中に、| (vertical bar)があると、400エラーが起こる解決法

## 背景

- TwitterのWeb Intent Tweetを、Wordpressから利用して、シェアする導線を強いたときに、ページタイトルに | (vertical bar)が存在した
- Twitter上のURLで、|(Vertical Bar)を利用すると、400エラーがでてしまう

## 試したこと

- ページタイトルに、urlencode関数でエンコーディングしてみたが、なぜか | (vertical bar)がエンコードされない

## 解決方法

- urlencodeした関数を、さらにstr_replace関数で、無理やり | (vertical bar)を変換
- `|`　はエンコードすると、`%7C` 

```php
<?php echo urlencode(str_replace('|', '%7C', $title)); ?>
```

## 最後に

かなり無理やり対応してしまったが、もっといいやり方があるような気がするので、ご教授いただけると嬉しいです。
SOQL query to find permission sets assigned to inactive users

#SOQLで非アクティブなユーザーに割り当てられた権限セットを検索する

```
SELECT Id, PermissionSetId, PermissionSet.Name, AssigneeId FROM PermissionSetAssignment WHERE AssigneeId IN (SELECT Id FROM User WHERE IsActive = false)
```
https://success.salesforce.com/answers?feedtype=RECENT&criteria=BESTANSWERS#!/feedtype=RECENT&dc=All&criteria=ALLQUESTIONS
CSSとは必要か

WordPress、ブログサービスがあるためCSSデザインはお任せになりました。そもそもコンテンツの質が重視される中で、デザイン性は2の次となっているのです。CSSカスタマイズをしただけでアクセスアップができたという話は少数派。

参考<a href="https://kaitori-coin.net/100-yen-commemorative-coins-purchase-price/" >100円記念硬貨買取</a>

最近では文章の中身だけでなく、デザイン性で順位上昇する例も出てきています。文章中心から総合的なサイトの評価をするようになりました。ただどちらが比重が置かれるかというと、デザイン（CSS)よりはコンテンツ（文章）が問われています。CSSをカスタマイズしていて、他のテンプレートに変える。元のテンプレートがSEOに悪ければアクセスアップ。あまり変化が出ないという例もあります。<a href="https://qiita.com/romlerw" >他の参考記事</a>
【UiPath】見やすいワークフロー作成①_アクティビティ表示名変更

#はじめに
UiPathでの開発を進めていくとワークフローの階層が深くなったり、変数にどんな値が入るか把握できなくなってきたり…
だんだんとワークフローが見づらくなってくることはありませんか？
この記事では「見やすい・わかりやすいワークフロー」を作成するためのポイントを記載していきます。
初めて開発する方にも、開発に慣れてきた方にもぜひ活用していただけたらと思います。

：環境：
Studio 2019.10.4 - 2020/02/06
Community License


#アクティビティの表示名を変更する
わかりやすいワークフローを作成するために、アクティビティの表示名を変更することをおすすめします。
アクティビティの表示名を変更することで以下のようなメリットがあります。
1．どのような操作をしているか理解しやすくなる
2．エラー箇所を見つけやすくなる
3．変数のスコープを把握しやすくなる
4．自分がどこの階層にいるか把握しやすくなる

それぞれ具体的に見てきたいと思います。

##1．どのような操作をしているか理解しやすくなる
アクティビティの表示名に処理の補足をいれることで、
何の画面を開いているのか、どの要素をクリックしているのかなどが一目でわかるようになります。

【変更前】
![変更方法_前.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/3d0ed653-79dc-f46a-4d46-8ee0f46792cc.jpeg)


【変更後】
![変更方法3_後.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/d04896a2-d9cc-888a-af3f-ca1af6d55882.jpeg)


[ブラウザーを開く]アクティビティの表示名に開くページを記載しておくと「ここでどんなWebページ開いてるんだっけ？」問題が解消されますね。


##2．エラー箇所を見つけやすくなる
エラーメッセージにはエラーになったアクティビティの名前が記載されていますが、
デフォルトのアクティビティの表示名のままだと、どのアクティビティでエラーが起きたかを把握するのに時間がかかってしまいます。
表示名を編集することで**エラーアクティビティを特定しやすくし、開発効率を高めることができます。**

【変更前】
![エラー1_矢印.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/b15ef25b-f79e-e17e-26e6-cbc6eea34586.jpeg)

【変更後】
![エラー2_矢印.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/924c6196-d8a6-5edd-2563-762dcd8f55c6.jpeg)



名前を変更することで「印刷ボタン押すところでエラーになった」とすぐわかりますね。

##3．変数のスコープを把握しやすくなる
画面下にある変数パネルを開くと、変数の一覧が確認できます。
ここで、**変数名**や**変数型**、**スコープ**を設定することができます。
(スコープとは、変数が使用できる範囲のことです。)

スコープを確認・変更する際に、アクティビティの表示名がデフォルトのままだと
どのアクティビティ内でその変数が使用されているのかわかりにくくなってしまいます。
**表示名を変更し、変数のスコープ管理をしやすくしましょう。**

【変更前】
![スコープ_矢印.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/5230933d-4bd7-5f3e-e6a4-295bc62c7f58.png)


【変更後】
![スコープ_変更後_矢印.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/f81b9a42-5d71-1ec3-bfa4-cca2caa9f85b.png)


##4．自分がどこの階層にいるか把握しやすくなる
開発が進み、アクティビティの階層が深くなってくると自分がどの階層で作業をしているか把握しにくくなることがあります。
ワークフローデザイナーの左上部分にはアクティビティの階層構造が表示されています。
表示名を変更することにより、この階層構造から**自分がどこの階層にいるのかわかりやすくなります。**
さらに移動したい階層を見つけるのも簡単になりますね。

【変更前】
![階層_矢印.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/35179510-1e7b-8a88-b193-6e1c9c7900e9.jpeg)


【変更後】
![階層_変更後_矢印.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/f3159fa8-ff30-b89d-a72e-11c737178dd5.jpeg)



では、肝心の表示名の変更方法を紹介していきます!

##5．アクティビティの表示名の変更方法
アクティビティの表示名を変更する方法は以下の2通りあります。
**1．アクティビティ名をクリックして編集**
![変更方法1_矢印.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/fbc2c834-b75b-af6a-ee8d-ae35ccbd14e5.png)


**2．[プロパティ]>[共通]>[表示名]を編集**
![変更方法2_矢印.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615615/bab44a3b-a34d-efa2-6987-c4f29b4c3f41.png)


簡単に変更できるのでパパっと変更してから次の作業に進むようにすれば、
後々自分をほめることになるはずです!:clap:

##まとめ
アクティビティの表示名を変更するだけでメリット盛りだくさんです。
**1．どのような操作をしているか理解しやすくなる**
**2．エラー時にどこでエラーになっているかが見つけやすくなる**
**3．変数の使用スコープが把握しやすくなる**
**4．自分がどこの階層にいるか把握しやすくなる**

自分だけではなく他の人が見る際にも助かるので ぜひぜひこまめなアクティビティ名の変更を!
nuxt でstoreの情報を取得して、computedで読み込むとスムーズに行かないない問題

# 問題
- vuexに保存しているデータを読み込むときに、まだ読み込み状態だった時、computedでデータを取得して表示する際に、読み込みがスムーズに行かなくてカクカク表示される。

#やりたいこと
- computedで読み込み完了までloading表示にしたい。

行ってみよう！

# いきなり答え！
```
<template>
    <loading :loading=loading></loading>
    {{results1}}
    {{results2}}
</template>
<script>
    import Loading from "~/components/Loading"

    export default {
        name: "index",
        components: {Loading},
        data: () => ({
            loading: true,
            readingResults1: false,
            readingResults2: false
        }),
        watch: {
            readingResults1: function (value) {
                if (value && this.readingResults2) {
                    this.loading = false
                }
            },
            readingResults2: function (value) {
                if (value && this.readingResults1) {
                    this.loading = false
                }
            },
        },
        computed: {
            results1: function () {
                let results = []
                this.$store.getters['hoge1'].forEach((obj) => {

                    let data
                    data = {
                        hogeId: obj.id,
                        hogeName: obj.name,
                    }
                    results.push(data)
                })
                this.readingResults1 = (results.length > 0)
                return results
            },
            results2: function () {
                let results = []
                this.$store.getters['hoge2'].forEach((obj) => {

                    let data
                    data = {
                        hogeId: obj.id,
                        hogeName: obj.name,
                    }
                    results.push(data)
                })
                this.readingResults2 = (results.length > 0)
                return results
            }
        }
    }

</script>
```

loadingがtrueの時に、ローディング状態になる。
で、ポイントは、

```
this.readingResults1 = (results.length > 0)
this.readingResults2 = (results.length > 0)
```
length取得で完了としている点。
これをwatchして

```
watch: {
    readingResults1: function (value) {
        if (value && this.readingResults2) {
            this.loading = false
        }
    },
    readingResults2: function (value) {
        if (value && this.readingResults1) {
            this.loading = false
        }
    },
},
```
ローディングをやめさせます。
AWS 基調講演メモ AWSomeday　セッション1-2

## AWSのグローバルインフラストラクチャネットワーク及びコンピューティング

### AWSの導入すると変わることは？
・スピーディーに、柔軟にリソースを提供できる
・支出が固定費から変動費に（データセンター）
・世界中でサービスが利用できる

### AWSのインフラ
20のリージョンと60のアベイラビリティゾーン

リージョン　＝　複数のアベイラビリティゾーンがある

#### AZ（アベイラビリティゾーン）
仮想ネットワークゾーン
複数のアベイラビリティゾーンのシステム実装がベストプラクティス

#### VPC(Virtual Private Cloud)
AZを跨って環境を作ることができる

#####パブリックサブネット
外部と通信できる

#####プライベートサブネット
VPC内部としか通信しない

###コンピューティングサービス（仮想サーバーのサービス）
####EC2
・仮想サーバー

####ELB
・インスタンス間で負荷を分散する
・ELB自体も負荷分散を行う。

####Auto Scaling
負荷に合わせて自動的にインスタンスを増減させる


##ストレージとデータベース

###EBS
EC2にくっつけて使うストレージ

###S3(Simple Storage Service)
共有サーバーと言われる
インターネット経由でアップロード・ダウンロードを行う。

###RDS
様々なデータベースが利用できる（MySQLなど）
RDSの場合は、データを入れるところから

####RDBMS
リレーショナルデータベース
⇨データは行と列を持つ
　複数の人が同時に更新できる

####レプリケーション
あるコンピュータやソフトウェアの管理するデータ集合の複製（レプリカ）を別のコンピュータ上に作成し、通信ネットワークを介してリアルタイムに更新を反映させて常に内容を同期すること。

####DBインスタンス
クラウド内の独立したデータベース環境
Electron透過ウィンドウを作って画面に情報をだすサンプル


## なに？

Electron というHTML/JavaScriptでアプリを作れるフレームワークを使って、画面を演出してみます。

通常のパソコンのデスクトップの上に、electron で作った透明ウィンドウを重ねてそこに文字なり画像なりを出す仕組みです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33095/464986e4-ac67-226f-bb24-7e8784daa7ef.png)

例えば、テレビのニュース番組みたいに天気予報を画面に出してみたり、ニコニコ動画風に画面にコメント流してみたり、ニュース速報出してみたり。そんなことが可能になります。

## サンプル

難しい説明はぬきにしてサンプルです。

以下のファイルを準備します。

```
  test/
    index.js
    index.html
    style.css
```


```javascript:index.js
"use strct";

const electron = require("electron");
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

let mainWindow = null;

app.on("window-all-closed", () => {
  if (process.platform != "darwin") {
    app.quit();
  }
});

app.on("ready", () => {
  mainWindow = new BrowserWindow({
    left: 0,
    top:0,
    frame: false,
    show: true,
    transparent: true,
    alwaysOnTop: true
    });

  mainWindow.setIgnoreMouseEvents(true);
  mainWindow.maximize();
  mainWindow.loadURL(`file://${__dirname}/index.html`);
  mainWindow.on("closed", () => {
    mainWindow = null;
  });
});
```

```html:index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="./style.css">
    <title>electron</title>
</head>

<body>
    <div id='sampleBox'>
        <p class='heart'>💛</p>
    </div>
</body>

<script type="text/javascript">
    window.onload = function () {
        autoHeart();
    }

    function autoHeart() {
        windowHeight = window.innerHeight;
        windowWidth = window.innerWidth;
        setInterval(() => {
            var sampleHearts = document.getElementsByClassName("heart");
            for(let i=0; sampleHearts.length; i++){
                sampleHearts[i].style.left = (Math.random() * windowWidth) + "px"
                sampleHearts[i].style.top = (Math.random() * windowHeight) + "px"
            }
        }, 1000)
    }
</script>

</html>
```

```css:style.css
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    height: 100%;
    width: 100%
}

body {
    height: 100%;
    width: 100%;
    background-color: rgba(0, 0, 0, 0.0);
}

canvas {
    height: 100%;
    width: 100%;
}

#sampleBox {
    width: 100%;
    height: 100%;
    position: relative;
    font-size: 100px;
}

.heart {
    position: absolute;
}
```

実行は簡単で、まず electron をインストールしておきます。

```console
npm install -g electron
```

そして今回作ったファイルの場所で実行します。

```
electron .
```

これで画面上にハートが ぱっ ぱっ が出てきたと思います。

## 次にやること

今回わかりやすくするため極力簡単なコードにおさめました。

そもそも electron がそうなのですが、サンプルコードを見ていただければわかりますが比較的シンプルに単なるHTMLとJavaScriptで出来ています。

あとは定期的にAPIをたたいてニュースを取得して画面にだす。 Twitter APIをたたいて何かだす。 天気予報をだす。 そんなことも比較的簡単にできますのでみなさんぜひ色々遊んでみてください！！
ASP.NET Core で全アクション共通で実行するロジックを実行する

# ASP.NET Core で全アクション共通で実行するロジックを実行する

\# 以下の記事が書かれた時の版数は .NET Core 3.1 (3.1.201), ASP.NET Core 3.1 (3.1.3) となります.

例えば `_Layout.cshtml` 内で本日のドル円レートを表示するとして、全てのコントローラの、全てのアクションに `ViewData` への代入を書いて回るのは流石にエレファント. そういう場合はどうすればいいかという話です.

プロジェクトに `Filters` フォルダを掘って、`MyFilter.cs` を作ります. 以下のように `IActionFilter` を継承したクラスを作ります. 非同期の場合は `IAsyncActionFilter` を継承します. `OnActionExecuting` はアクション実行前、`OnActionExecuted` はアクション実行後に発火します. `context.Controller` を `Controller` にキャストすると `ViewData` にアクセスできます.

```csharp
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace WebApplication1.Filters
{
    public class MyFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            var c = context.Controller as Controller;
            c.ViewData["foo"] = "bar";
        }
    }
}
```

このフィルタが使われるようにするため、`Startup.cs` を開き、`ConfigureServices` メソッドの中の `AddControllersWithViews` を以下のように書き換えます.

```csharp
services.AddControllersWithViews(options =>
{
    options.Filters.Add(typeof(MyFilter));
});
```
ElasticsearchのScriptでupsertをする

## memo

Elasticsearch内で配列要素の追加、更新を行う方法を書きたいと思います。
mapping情報を以下とした場合、appというindexのusers配列に複数のuserがいます。
この場合に、user情報を新規登録、更新する場合のクエリを紹介したいと思います。

```
{
    "app": {
        "mappings": {
            "_doc": {
                "properties": {
                    "name": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "users": {
                        "properties": {
                            "pass": {
                                "type": "text",
                                "fields": {
                                    "keyword": {
                                        "type": "keyword",
                                        "ignore_above": 256
                                    }
                                }
                            },
                            "user": {
                                "type": "text",
                                "fields": {
                                    "keyword": {
                                        "type": "keyword",
                                        "ignore_above": 256
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

### サンプルデータ

Elasticsearchには既に以下の情報が入っているとします。

```
{
	"name": "qiita",
	"users": [
		{
			"user": "admin",
			"pass": "admin"
		}
	]
}
```

### Query

params.userとparams.passのみ可変

```
{
	"query" : {
		"term" : { "name" : "qiita" }
	},
	"script" : {
		"lang" : "painless",
		"inline" : "def user = new HashMap();def exist = -1;for( int i = 0; i < ctx._source.users.length; i++){ if(ctx._source.users[i].user==params.user){ exist = i ;ctx._source.users[i].pass=params.pass; } } if(exist <0){ def userInfo = new HashMap();userInfo.puts('user',params.user); userInfo.puts('pass',params.pass);ctx._source.users.add(userInfo)}",
		"params" :{ //追加、更新したい情報を設定
			"user" : "admin", 
			"pass" : "admin"
		}
	}
}
```

### 実際の動作(追加)

```
params=
{
	"user" : "user",
	"pass" : "pass"
}
```

結果(_source抜粋)

```
{
	"name": "qiita",
	"users": [
		{
			"pass": "admin",
			"user": "admin"
		},
		{
			"pass": "pass",
			"user": "user"
		}
	]
}
```

### 実際の動作(更新)

```
params=
{
	"user" : "admin",
	"pass" : "pass"
}
```

結果(_source抜粋)

```
{
	"name": "qiita",
	"users": [
		{
			"pass": "pass",
			"user": "admin"
		},
		{
			"pass": "pass",
			"user": "useer"
		}
	]
}
```

### 最後に

ElasticsearchのScriptで利用するpainlessという言語は、Javaライクで書くことが出来て、
個人的には親しみやすいです。
個人的には、scriptでinner_hitsの情報も使えるようになるとよりありがたいんですが、どうなんでしょう。
Amazon ECSの作成済みクラスターでContainer Insightsが有効化できた

昨年(2019年)からAmazon CloudWatch を利用することで、Amazon ECSのリソースを監視できるようになりましたが、既存のECSクラスターの場合、AWSマネジメントコンソールだと、Container Insightsをあとから有効化することができませんが、`aws-cli` だと設定できるのがわかったのでメモ。

作成時に設定(Container Insights を有効にする)できるけど
<img width="843" alt="スクリーンショット 2020-04-06 14.30.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/a83e7019-2dc2-1ee9-0e90-c5cd654d77cd.png">

更新時に設定はできない(設定項目がない)
<img width="1211" alt="スクリーンショット 2020-04-06 14.31.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/05593e8a-7242-46ba-3fdb-c1ac6c1f778f.png">


## Amazon ECS向けAmazon CloudWatch Container Insightsについて

下記記事が参考になります。

Amazon ECS向けAmazon CloudWatch Container Insightsについて | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/introducing-container-insights-for-amazon-ecs/

また、収集されるメトリクスについては下記が参考になりました。

Amazon ECS Container Insights のメトリクス - Amazon CloudWatch
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Container-Insights-metrics-ECS.html



## 設定方法

下記ドキュメントに有効/無効化の手順があります。

Setting Up Container Insights on Amazon ECS for Cluster- and Service-Level Metrics - Amazon CloudWatch
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-ECS-cluster.html


### クラスターごとに設定

既存クラスターに対して有効/無効化するコマンドは下記となります。
`--cluster` パラメータはクラスター名とARNのどちらでも指定できました。

```console:有効化
> aws ecs update-cluster-settings \
  --cluster <クラスターの名前 or ARN> \
  --settings name=containerInsights,value=enabled
```

無効化するにはこちら。

```console:有効化
> aws ecs update-cluster-settings \
  --cluster <クラスターの名前 or ARN> \
  --settings name=containerInsights,value=disabled
```



### アカウントレベルで設定

アカウントレベルで設定できるとドキュメントにありますが、手元の環境では期待した結果となりませんでした。

Setting Up Container Insights on Amazon ECS for Cluster- and Service-Level Metrics - Amazon CloudWatch
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-ECS-cluster.html


>(Google翻訳) すべての新しいクラスタでContainer Insightsをデフォルトで有効にするには、次のコマンドを入力します。
>
>上記のコマンドを使用して、デフォルトですべての新しいクラスターでContainer Insightsを有効にしていない場合は、次のコマンドを入力して、Container Insightsを有効にして新しいクラスターを作成します。次のコマンドが機能するには、AWS CLIのバージョン1.16.200以降を実行している必要があります。

コマンドはこちら。

```console
> aws ecs put-account-setting \
  --name "containerInsights" \
  --value "enabled"
```

- 期待: 既存クラスターでContainer Insightsが有効になる
- 結果: 既存クラスターでContainer Insightsは無効のまま

上記コマンドを実行後にAWSマネジメントコンソールでクラスターの作成画面を開いてみても「Container Insightsを有効にする」にデフォルトでチェックが入るわけでもなく、コマンド実行による挙動がよくわかりませんでした。

詳しくご存じの方がおられましたらコメントお願いします！

## 参考

Amazon ECS向けAmazon CloudWatch Container Insightsについて | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/introducing-container-insights-for-amazon-ecs/

Amazon ECS Container Insights のメトリクス - Amazon CloudWatch
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Container-Insights-metrics-ECS.html

Setting Up Container Insights on Amazon ECS for Cluster- and Service-Level Metrics - Amazon CloudWatch
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-ECS-cluster.html
Does a Lightning Component know if it is in a Community or a standard Lightning Salesforce page?

#Lightning コンポーネントでコミュニティーか通常の組織環かどうかを見分ける方法

https://salesforce.stackexchange.com/questions/142710/does-a-lightning-component-know-if-it-is-in-a-community-or-a-standard-lightning

Lightning component .cmp
<aura:component implements="force:hasRecordId, force:appHostable, flexipage:availableForAllPageTypes, forceCommunity:availableForAllPageTypes" controller="CustomController">
	<aura:handler name="init" value="{!this}" action="{!c.init}"/>
</aura:component>

Apex controller .cls
public with sharing class CustomController {
    @AuraEnabled
    public static boolean isCommunity(){
        Id siteId = Site.getSiteId(); // take a look at the apex class Site, you may find more useful method concerning site/community
        if (siteId != null) {
            return true;
        }
        return false;
    }
}

Lightning component controller .js
({
	init : function(component, event, helper) {
        var action = component.get("c.isCommunity");
        action.setCallback(this, function(response) {
            var isCommunity = response.getReturnValue(); // do any operation needed here
        });
        $A.enqueueAction(action);
    }
})
オンライン上でSwiftのコードを実行する

# 背景
　MacBookProを買ってはや4年。playgroundの動きが遅く（というより実行できなく）なってしまったので、オンライン上でSwiftのコードを実行できるサービスを調べてみました。

# オンライン上でSwiftが実行できるサービス

### paiza.IO
https://paiza.io/ja/projects/new?language=swift

- Swift5対応
- 他言語にも数多く対応

### iSwift
https://iswift.org/playground


- Swiftのバージョンを切り替えることが可能（2.2, 3.1, 4.0）
Google Maps View アセットを使ってつまずいた点

# 背景

最近、Unity で[スプリングセール](https://assetstore.unity.com/?on_sale=true)が開催されておりまして、その中で、「Google Maps View」というものも対象になっていましたので購入してみたことが始まりでした

# 試行錯誤

アセットに含まれるサンプルシーンを実機で動かそうとあれやこれやをしてみることにしました。使用した環境は以下の通り。

```
OS: Windows10 64bit
Unity: 2019.3.10f1
Smartphone: Sony Xperia Z5
```

とりあえず、マップが表示されるところまで行ったのですが、現在進行系を含めていくつかの場面でつまりました…。

## ビルドがストールする(謎)

最初から完全に想定外でしたが、数回目のビルドでいきなりビルドがストールしました。
ストールしたのはサンプルシーンをビルドしようとした瞬間。そこから完全にUnityが固まってしまい、結局タスクマネージャーでプロセス落とさないといけない事態に陥りました。

とにかく原因を整理しようと、新しいプロジェクトでビルドすると問題なく完了して実機でアプリが動きました。

続いて、Unity2018 ではどうかと試してみたのですが、ビルドは完了できる。

この先は…と思ったのですが睡魔に勝てずそのまま就寝。

…そして、後日ビルドしてみると… **問題なくできました** 。

変更したのは、「プレイヤー設定」→「公開設定」→「ビルド」の「Custom Main Manifest」のチェックを外したことだけ…はて、何が原因だったのか頭を抱える日々です。

## マップが表示されない(解決)

さて、Unity2019 でビルドできて実機で検証できるようになったのですが、今度は **マップが表示されない** 。

またしても孔明の罠か！ と思いましたが、単純なミスでした。

試行錯誤をしているうちに、 **パッケージ名を変えていたのを忘れていた** のです。

このアセットは Google Map API の認証を Google Cloud Platform のダッシュボードページで設定するのがマストなのですが、 SHA-1 フィンガープリントを登録しているパッケージ名と違ったものにしていました。

パッケージ名を適切なものにすると無事マップが表示されました…。

## 朝なのにマップがナイトモード(解決)

実はこのプログラムが動いたのがこの原稿を書いているちょっと前(午前7時)でして、マップは昼間のものを描画しているはずなのですが、なぜか表示されるのはナイトモード。どう見ても違和感がありすぎます。

![Screenshot_20200422-073112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101034/f9c0c347-d8db-6a7e-1910-7df66cc5bc44.png)


おそらく、アプリの中では「現在は夜」だからこうなっているのは容易に想像はつくのですが、これを踏まえると、「**アプリの時間帯が　GMT で固定されていない？**」という仮定が生まれました。

色々調べてみたいことはあるのですが、他にやりたいこともあるので、とりあえずサポートの Discord に~~丸投げ~~問い合わせしてみて、今返事待ち中です(おい！)。

### 追記

Discord での質問にリプライが付きました。

[Discord 上での回答](https://discordapp.com/channels/512252380071460885/512604632749441039/702405493204975666)

すると、マップの色分けは自動的に変わるのではなく、設定用の JSON を組み込むことであの色設定を行っていたようです。わたしたちがよく見る Google Map の表示は、

```JSON
[]
```

と記述すれば OK だそうです。実際に設定したら、見た目がいつものマップ画面になりました。

ということで、本件はここで解決です。


# さいごに

こういう悪戦苦闘は楽しい
SQLの処理の流れ

SQLを学習するうえでこの処理の流れを意識しながら
学習すると覚えやすかったので、もし誰かの一助に慣れればと思い投稿しました。

まず句の記述順序ですが

```SQL:example.sql
SELECT ○○ FROM テーブル名 WHERE 条件 GROUP BY 集約キー HAVING 条件 ORDER BY ソートキー;
```
このように記述をすると決まっています。
SELECT句には表示用に別名をつけることが出来る機能(AS)があるのですが
この別名をGROUP BYには使うことが出来ません。
しかし、ORDER BYには使うことが出来ます。
上の記述を見るだけだと理由は分かりにくいのですが、内部の処理を意識しながら
見てみると非常にわかりやすいです。

SQLの処理は下記①〜⑥の順番に行われています。
①FROM・・・・・・・・テーブルから参照
②WHERE ・・・・・・・選択する行の条件を設定
③GROUP BY・・・・・・グループごとに集約
④HAVING ・・・・・・・グループに集約した結果に対して条件指定
⑤SELECT ・・・・・・・出力する列の名前
⑥ORDER BY・・・・・・検索結果を並べ替える

この処理の順番を意識しながら考えて見ましょう。
別名をつける機能(AS)は⑤番目で行われていますが、
GROUP BYは③番目で行われており別名が付けられる前に処理が終わってしまっています。

今度はORDER BYを見てみると⑥番目での処理になっているので
別名を付けてからの処理になっているので別名を使うことが出来るんですね。

プログラミング学習は暗記しようとしてはいけないというのはその通りなのですが
こういった基本的な処理の流れは覚えておくと覚えやすそうですね。
(覚えずにググるとしても、処理の流れも意識すると良いさそうですね)
[Swift]Int型の配列をString型の配列に変換する

# 配列の型変換
mapを使えば簡単にできます。
もちろん、Int -> Stringではなくても可能です。

```Swift
let hour = [Int](0...23).map{return String($0)}
```
# 参考サイト
https://qiita.com/Kenya/items/dced88c4508302786f24
Firebase FunctionsのエミュレーターでもGoogle API用のアクセストークンを得る方法

Firebase、いつの間にかとても練れた内容になってきてました。
というわけでバリバリ使っておりますが、たまにドハマリし、かつ英語で検索してすら情報ほぼゼロ、ということがあります。
そんな中の「え、これでいいの？」をご紹介します。
今回の内容はタイトルそのまんま、です。

# 概要

* Firebase Cloud Functions内で、Google API用のアクセストークンを得たい
    * クライアントサイドでFirebase使いまくりのSPAがあり、そのSPA内からGoogle APIサービスを叩きたい
    * が、SPA内にAPIキーを埋め込みたくない
    * ので、アクセストークンをFunctions内で得、それをSPAに渡したい
* 超素朴実装をすると、デプロイした実クラウド上ではちゃんと動作するが、ローカルPC上で動作させたエミュレーター上では動作しない
* ものすごく簡単な解決方法があるが、あまりネット上には出ていない模様

# レギュレーション

* Firebaseプロジェクト作成済み
    * 管理者認証情報作成済み＆配置済み＆環境変数で指定済み
    * プロジェクトに紐付いた、利用したいGoogle APIを有効化済み
* Firebase Cloud Functions およびローカルPC上のエミュレーター
    * Functions用の `index.js` で `admin.initializeApp()` を呼び出し済み
* Node v8

# 実クラウド上では動作するがエミュレーターでは動作しないコード

```node:index.js
exports.getAccessToken = functions.https.onCall(async (data, context) => {
  // カスタムクレームによる権限認証をここで行う
  try {
    const response = JSON.parse(await request({
      url: 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token?scopes=https://www.googleapis.com/auth/cloud-platform',
      headers: {
        'Metadata-Flavor': 'Google'
      }
    }));
    if (!response.access_token) {
      throw new Error('bad response ' + JSON.stringify(response || {}));
    }
    return response;
  } catch (e) {
    throw new functions.https.HttpsError('aborted', e.message);
  }
);
```

要は [Google CloudのIDとアクセストークンの取得](https://cloud.google.com/run/docs/securing/service-identity) に出ているのをそのままNodeに翻訳しただけです。そしてこれで、実クラウドではきちんと動きます。

しかし、エミュレーター上ではこれは動作しません。

```
getaddrinfo ENOTFOUND metadata.google.intenral
```

…そりゃするわけないわ！ `http://metadata.google.internal/` ってどんなFQDNだよ！！ っていう単純な話です。これは有名なメタデータサーバー、GCEインスタンスから参照できるアドレスであり、 **FunctionsだってGCE（的ななにか）の上で動いているんだから参照可能だけどローカルでは参照できるわけないだろヴォケ**、です。

# 解決策

```node:index.js
exports.getAccessToken = functions.https.onCall(async (data, context) => {
  // カスタムクレームによる権限認証をここで行う
  try {
    return await admin.app().options.credential.getAccessToken();
  } catch (e) {
    throw new functions.https.HttpsError('aborted', e.message);
  }
);
```

え、これでいいの…？ というワンライナーになってしまいました(^^ゞ

実はFirebase Admin SDKの `admin.credential.Credential` クラスに `getAccessToken` っていうそのまんまのメソッドが生えていて、これを呼び出せば、先述の実クラウドで動作するものと同じフォーマットのJSONが得られます。

そして、管理者認証情報つきで初期化済みのAdmin SDKの `App` インスタンスは、`options` プロパティーの中に `credential` プロパティーを抱えているわけです。

# 謎（調べてないだけ）

しかしこれ、Functionsエミュレーターはどうやってエミュレートしてるんですかね、メタデータサーバーを…何か秘密の口がFirebase側に生えてるのかしら？