OmniAICreator/Qiita-1.07M huggingface dataset:
【OCI】FastConnectについていろいろ #2(接続モデル)

###はじめに

前回はFastConnectのサービス概要、基本情報について触れさせていただきました。
今回はFastConnectの接続モデルについてご紹介できればと思います。


###FastConnect接続モデル
FastConnectの接続モデルは以下の通り接続方法によって3パターンに分かれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/2e03bd22-c986-cf7b-8363-5bef73db1124.png)


①Oracleプロバイダ
プロバイダ設備(Partner Edge)とオラクル設備(Oracle Edge)間の物理回線はすでに敷設/接続済みです。
Oracleプロバイダのキャリア網/専用線サービスを契約しているユーザが既存網とOracle Cloudとの接続を
希望する場合にPartnet EdgeとOracle Edge間で<font color="red">**予め接続してある物理回線の中から
仮想回線(Virtual Circuit)の形で提供**</font>することによりOracle Cloudと接続するための経路を確保します。
この場合、<font color="red">**物理回線は複数ユーザで共有**</font>することになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/42b48a0a-e9b2-d841-3f76-e2cf9a67eb0b.png)


②サードバーティ・プロバイダ
サードパーティ・プロバイダはOracleプロバイダ以外でOracle Cloudとの接続サービスを
提供するプロバイダのことをいいます。
<font color="red">**Oracleプロバイダとの違いはPartnet EdgeとOracle Edge間の回線の提供方法にあります**</font>
Oracleプロバイダはすでに敷設/接続済みの物理回線の中から仮想回線(Virtual Circuit)の形で提供するのに対し、
サードパーティ・プロバイダは<font color="red">**ユーザごとに敷設・接続しての提供**</font>になります。
この場合、<font color="red">**物理回線は1つのユーザで占有**</font>することになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/4e1e0317-3a65-0c5c-7378-0018d8e307e0.png)

③コロケーション
FastConnect Locationにコロケーション環境を持つ場合はユーザ自身がユーザ環境(Customer Cage)と
Oracle Edge間の物理接続を用意してOracle Cloudと接続することができます。

<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/3205bbdd-584d-6761-32d7-e516b93750be.png">


###参考情報
①Oracleプロバイダ・リスト
<font color="red">**[・Tokyo region][1]**</font>
<font color="red">**[・Osaka region][2]**</font>

[1]:https://www.oracle.com/jp/cloud/networking/fastconnect/providers/#:~:text=%E3%81%AF%E3%81%84-,%E6%9D%B1%E4%BA%AC%E3%80%81%E6%97%A5%E6%9C%AC,%E6%9D%B1%E4%BA%AC%20%2D%20Equinix,-%E3%82%A2%E3%83%83%E3%83%88%E6%9D%B1%E4%BA%AC
[2]:https://www.oracle.com/jp/cloud/networking/fastconnect/providers/#:~:text=%E3%81%AF%E3%81%84-,%E5%A4%A7%E9%98%AA%E3%80%81%E6%97%A5%E6%9C%AC,%E5%A4%A7%E9%98%AA%20%2D%20NTT%E3%83%87%E3%83%BC%E3%82%BF,-%E3%82%A2%E3%83%83%E3%83%88%E6%9D%B1%E4%BA%AC

②関連ドキュメント
<font color="red">**[・Oracleパートナー(プロバイダ)の使用][3]**</font>
<font color="red">**[・サードパーティ・プロバイダの使用][4]**</font>
<font color="red">**[・FastConnect: Oracleとコロケート][5]**</font>

[3]:https://docs.oracle.com/ja-jp/iaas/Content/Network/Concepts/fastconnectprovider.htm
[4]:https://docs.oracle.com/ja-jp/iaas/Content/Network/Concepts/fastconnectthirdpartyprovider.htm
[5]:https://docs.oracle.com/ja-jp/iaas/Content/Network/Concepts/fastconnectcolocate.htm

###まとめ
今回はFastConnectいろいろの第2回目として接続モデルについてご紹介しました。
各接続モデルの特徴について簡単にまとめると以下の通りになると思います。

①Oracleプロバイダ
プロバイダ設備とOracle設備間がすでに接続されており
仮想回線の作成のみでOracle Cloud間の経路が確保できるため
<font color="red">**申込から開通までの納期が短いこと**</font>が特徴と言えます。

②サードバーティ・プロバイダ
プロバイダ設備とOracle設備間をユーザごとに専用の物理回線で接続するため
<font color="red">**高いセキュリティとパフォーマンス**</font>が特徴です。

③コロケーション
FastConnect Location内の短距離における接続になるため<font color="red">**配線のコストが安価**</font>な上、
<font color="red">**接続モデルの中で最も高いパフォーマンスが出せるモデル**</font>になります
【OCI】FastConnectについていろいろ #1(サービス概要)

###はじめに

オンプレミス拠点とOracle Cloud間を閉域網 or 専用線経由で接続する場合に利用する「FastConnect」について
サービス概要をはじめ利用可能なプロバイダ、構成パターン等についてお伝えしようと考えています。


###サービス概要
FastConnectはお客様設備(データセンター等)とOracle Cloud間をインターネットを経由しない
専用線や閉域網といったプライベート回線経由で接続するためのサービスです。

###FastConnectサービスの特徴
①信頼性の高いクラウド接続サービス
可用性(Availability)に対してSLA(99.9%)が設定されており高い信頼性を確保している
②プライベート接続
インターネットを経由することなく、信頼できるエンドポイントのみを経由するため、プライバシが向上
③高スケールのワークロードのサポート
1Gbps, 10Gbps, 100Gbpsの高帯域ポートを提供
要望に応じて柔軟にスケールアップまたはスケールダウンが可能
④予測可能で経済的
トラフィック量(inbound/outbound)の課金がないため正確なコスト予測が可能
<font color="red">**[ポート課金][1]**</font>が安価なため、トラフィック量の多いワークロードであるほど経済的

[1]:https://www.oracle.com/jp/cloud/networking/fastconnect/pricing/


###構成イメージと責任分担

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/286614ab-5535-4bcb-9860-758318ff89f2.png)

(構成要素について)
①CPE
外部との通信を行うためにお客様拠点またはデータセンターに設置する機器(主にルータ)

②キャリア網、専用線
通信プロバイダが提供する拠点間接続のためのサービス(インターネットを経由しない)
代表的なものとしてNTTコミュニケーションズのAcrstar Universal Oneなどがある

③FastConnect Location
Oracle Cloudに閉域網 or 専用線経由での接続を提供するための設備が置かれている場所
お客様は自社ネットワークとOracle Edge間を接続することにより
Oracle Cloudとの相互通信が可能になる
Oracle社はOracle Edgeのポート(物理 or 仮想※提供帯域は1G,10G,100G)までを提供する
なお、FastConnect Locationの場所は公開されており
日本の場合、Tokyo RegionのFastConnect Locationは「Equinix, TY4」に
Osaka RegionのFastConnect Locationは「NTTデータ, Dojima Bldg 4」にある。
<font color="red">**[APAC Oracle FastConnectロケーション][2]**</font>

[2]:https://www.oracle.com/jp/cloud/networking/fastconnect/providers/#:~:text=APAC%20Oracle%20FastConnect%E3%83%AD%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3




④Customer/Partner edge
Oracle EdgeとBGPピアリングするためのBGPルータ

⑤Oracle Edge
お客様ネットワークとOracle Cloud間を接続する際のOracle Cloud側の機器
Customer/Partner EdgeとBGPピアリングを行う

⑥Partner Cage
Customer/Partner Edgeが設置されているラックのこと
Oracle社からの貸し出し/代理契約は不可能であるため
お客様とFastConnect Locationのデータセンター間で直接ご契約が必要

⑦Oracle Cage
Oracle Edgeが設置されているラックのこと


###Customer/Partner EdgeとOracle Edge間接続イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/00cb0a81-e521-e43d-7edd-5d2ada959aea.png)

###FastConnect接続モデル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/85c15c09-0691-4991-2f96-2abee883f967.png)


###まとめ
今回は「FastConnectについていろいろ」の第1回目としてFastConnectの概要とサービスの
基本情報について触れてみました。
次回はFastConnectの各接続モデルについて詳しく説明させていただこうと考えていますので
引き続き宜しくお願い致します。
【Ruby＋rubocop】RuboCopでコーディングチェックする。

自分用のメモとして残します。




# やり方
前提として、rubocopをインストールしていること。




## チェックのみ：ファイル単体

```zsh
bundle exec rubocop ファイルパス
```


## チェック＆自動整形：ファイル単体、-a オプション
-a オプションで自動整形できるものはしてくれる。
--auto-correct の略

```zsh
bundle exec rubocop ファイルパス -a
```
以上です。
ターミナルで目的のフォルダに簡単に移動する方法

ターミナルで目的のフォルダに移動するにはcdコマンドを使用します。

cd パス【Enter】

深いディレクトリに移動するには長いパスをタイプする必要があり、面倒です。
実は、Finderからターミナルにディレクトリをドラッグ&ドロップすることによりパスを簡単に入力できます。

1. 「cd 」までタイプする
2. Finderからターミナルに目的のディレクトリをドラッグ&ドロップ
3. マウスボタンを放すとパスが入力される
[Oracle Cloud] Autonomous Databaseのメンテナンスは何をするの？影響は？

Oracle Cloud Infrastrcture（OCI）の特徴的なサービスの1つであるAutonomous Databaseはオラクル社がメンテナンスをしてくれます。メンテナンスとは何をするの？どのくらい時間がかかる？メンテナンス中はサービスを使えるの？など疑問を調べてみました。

# Autonomous Databaseとは？
Autonomous Databaseは、自律型データベースと呼ばれているデータベースのマネージド・サービスです。今まではDB管理者と呼ばれる人が担当していたデータベースのチューニングやパッチ適用、バックアップなどの作業が自動化されているサービスになります。
メンテナンス作業をOracleに任せるため、毎週末にメンテナンス時間が取られています。Autonomous DatabaseはExadata上のRACの上で稼働しているサービスなので、内部的にはメンテナンスされるノードから違うノードに移行されるため、基本的に瞬断が発生する程度です。アプリケーションにリトライ機能があれば比較的業務影響は少ないと思われますが、とはいえメンテナンス時間は意識しておきたいものです。
そのため、この記事ではAutonomous Databaseのメンテナンス時間の確認方法をまとめました。

# Autonomous Databaseのメンテナンス時間の調べ方
メンテナンス時間を調べるには、ADWの詳細画面から「メンテナンス」の部分を確認します。次回のメンテナンスの予定が記載されています。ここでは次回土曜日のUTC6～8時でメンテナンスが実施される予定だと確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581985/d9072515-7992-d49a-3b46-2c6e682deb39.png)

では実際にいつメンテナンスが行われていたのでしょうか？「履歴表示」のリンクをクリックすると、過去に実施されたメンテナンスの時間が確認できます。基本的に毎週実施されているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581985/55ad8a83-e95b-e00b-09f5-75eca45f4965.png)

# Autonomous Databaseのメンテナンスでは何が行われているの？

マニュアルの「[Oracle Autonomous Databaseの職責モデル](URL=https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/shared-responsibility-model.html)」にある通り、パッチ適用などのメンテナンスはオラクル社にて実施されます。[こちらの資料](URL=https://speakerdeck.com/oracle4engineer/adb-s-technical-detail-jp?slide=117)によるとFirmware/OS/HyperVisor/Clusterware/Databaseなど全てのコンポーネントに対するメンテナンスが行われます。

# メンテナンスによってどんな影響があるの？

[上記と同じ資料](URL=https://speakerdeck.com/oracle4engineer/adb-s-technical-detail-jp?slide=117)に、アプリケーション（既存セッション）に対する影響の記載があります。
・多くのパッチはオンラインで適用できるため影響なし
・オンライン適用不可のパッチはRACのローリングアップグレードで適用されるので影響なし（接続中セッションの瞬断の可能性があるが、すぐ再接続可能）
・どうしてもサービス停止が必要となるメンテナンスについては、事前に通知の上で実施

つまり、基本的にはメンテナンス中もサービスは利用可能ということですね。ただ[こちらのページ](URL=https://speakerdeck.com/oracle4engineer/adb-s-technical-detail-jp?slide=119)に記載がある通り、「トランザクションがDBで完結しないジョブ」などは注意が必要そうです。

# 定期メンテナンスの通知は来るの？

定期メンテナンスについてはデフォルトで通知は来ないようです。メトリック監視機能を設定することで、指定したメールアドレスにメールの送付ができるようです。下記のイベントが発生すると通知ができますので、メンテナンス時間を意識する必要がある人は通知をうまく利用しましょう。
・ScheduledMaintenanceWarning:計画メンテナンスの開始時間の1時間前と24時間前に通知
・MaintenanceBegin:メンテナンスの開始（事前定義された時間ではなく、実際にメンテナンスが開始された時間）
・MaintenanceEnd:メンテナンスの終了（同じく実際にメンテナンスが終了した時間）
・NewMaintenanceSchedule:次回メンテナンスの予定（メンテナンス終了時に通知）

# まとめ

Autonomous Databaseのメンテナンスについて調べました。通知などを上手く使いこなせば、Autonomous Databaseのメリットである「データベースのメンテナンスをオラクル社にお任せできること」を享受して楽にデータベース運用ができそうですね。
本番環境でプリコンパイルができませんよ｡｡

## はじめに
Rails Tutorialを学習中に下記のエラーが発生しました｡

```shell:terminal
Minitest::UnexpectedError:         DRb::DRbRemoteError: Asset `application.css` was not declared to be precompiled in production.
        Declare links to your assets in `app/assets/config/manifest.js`.
        
          //= link application.css
```
まず開発環境でレンダリングを試しても問題なかったので､エラー文通り **本番環境で稼働する際にプリコンパイルできないし宣言されてないよ!!** と怒られたみたいです｡｡｡

### 開発環境
- HostOS: windows11 Home
- GestOS: ubuntu/xenial64
- ruby: 2.7.5
- Ruby on Rails: 6.1.6

## なぜ発生したのか
静的アセットやCSSは､sprocketsでコンパイルしています(動的アセットはwebpacker｡rails6.x以降のデフォルト設定)｡

cssの拡張言語であるsass(厳密にはscss)で記述しており､cssからsassに変更した際にプリコンパイルの設定ファイル(app/assets/config/manifest.js)を変更していないのが原因でした｡

```javascript:app/asstes/config/manifest.js
//= link_tree ../images
// = link_directory ../stylesheets .css ←ここ
```


## 解決方法
修正方法は､とても簡単です｡

cssの管理は､application.scssで行っています｡
```ruby:app/assets/stylesheetes/application.scss
@import 'bootstrap-sprockets';
@import 'bootstrap';
@import 'mixin';
@import 'partials/*'
```

ですので､先程のmanifest.jsをファルダではなくファイルを直接参照するように設定します.

```javascript:app/assets/config/manifest.js
//= link_tree ../images
//= link application.css ←追加
```

これで先程のエラーは解消することができました‼

***
#### 参考文献
[Asset application.css is not declared but it is declared in manifest](https://stackoverflow.com/questions/46391220/asset-application-css-is-not-declared-but-it-is-declared-in-manifest)
[Rails 7.0でアセットパイプラインはどう変わるか](https://www.wantedly.com/companies/wantedly/post_articles/354873)
kintoneプラグイン開発してみてメモっておきたいこと

# 環境
- kintone
- javascript
- html
- css

# 対象
- kintoneプラグイン開発を始めたい人

# 役立ったもの
### create-pluginを使って雛形を作る
公式が用意してくれているcreate-pluginを使ってプラグインに必要なセットを簡単に用意できます
ビルドとアップロードも可能です。
https://developer.cybozu.io/hc/ja/articles/360000877946



### 設定画面を作成する
Kinetoneと同じようなUIを作成できるようなCSSを公式が用意してくれています
https://developer.cybozu.io/hc/ja/articles/203302214-kintone%E3%83%A9%E3%82%A4%E3%82%AF%E3%81%AA%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%82%B7%E3%83%BC%E3%83%88%E3%81%AE%E5%88%A9%E7%94%A8

※create-pluginには初めから入っています

### 設定値のGet/Set
- set
https://developer.cybozu.io/hc/ja/articles/203661160#step2
※プラグインの設定画面でしか使用できないので注意
**例**
```javascript
const config = {
  'key1': 'value1',
  'key2': 'value2'
};
kintone.plugin.app.setConfig(config);
```
- get
https://developer.cybozu.io/hc/ja/articles/203661160#step1
**例**
```javascript
(function($, PLUGIN_ID) {

let config = kintone.plugin.app.getConfig(PLUGIN_ID);
console.log(config['key1']);

})(jQuery, kintone.$PLUGIN_ID);

```
### 各画面のトリガー
- レコード一覧イベント
https://developer.cybozu.io/hc/ja/articles/201941964

- レコード詳細イベント
https://developer.cybozu.io/hc/ja/articles/201941974

- レコード追加イベント
https://developer.cybozu.io/hc/ja/articles/201941984

- レコード編集イベント
https://developer.cybozu.io/hc/ja/articles/202166270

### よく使ったAPI
- レコードの取得（GET）
https://developer.cybozu.io/hc/ja/articles/202331474

### よく使った情報取得
- レコード詳細情報取得
https://developer.cybozu.io/hc/ja/articles/201942014

- アプリの ID を取得する
https://developer.cybozu.io/hc/ja/articles/202166300

### 色々見たリンク集
- kintone API
https://developer.cybozu.io/hc/ja/articles/360028177472

- プラグイン開発
https://developer.cybozu.io/hc/ja/sections/200644024

- cybozu developer コミュニティ
https://developer.cybozu.io/hc/ja/community/topics
Google Apps Script　デバッグ（新IDE対応）参考サイト


https://tenshoku-miti.com/takeshi/google-apps-script-debug-method-cvcountnone/

## Logger.log()の使い方

`Logger.log()`関数は、 __引数のデータをそのまま出力__ します。引数に変数を指定する事もできます。


## エラー

### TypeError: Cannot read property 'getRange' of null

https://teratail.com/questions/270420
セキュリティのトレンドを知っておくために役立つサイト

タイトルの通り、セキュリティ関連のトレンド情報を知っておきたい人向けのサイト。
良ければ参考までに。

# 毎日チェック用のサイト
動向を確認する際に見ているサイト

[ScanNetSecurity](https://scan.netsecurity.ne.jp/category/incident/)

[IPA 情報処理推進機構](https://www.ipa.go.jp/security/vuln/index.html)

# じっくり読みたい系のサイト
毎日では無いですが、時間が空いたときに眺める系

[トレンドマイクロ セキュリティニュース](https://www.trendmicro.com/ja_jp/security-intelligence/breaking-news.html)

[ZDNet Japan](https://japan.zdnet.com/security/)


他にも良さげなサイトあれば教えてほしいです。
【Django】DjangoはMVCじゃないの？Railsとの比較とMTVについて

## はじめに
こんにちはk_ukiです。
　この度、Pythonのwebフレームワークである、「Django」を使用する機会が来たため、そのキャッチアップをおこなっております。
　今までは、Rubyのフレームワークである「Ruby on Rails」をよく使用していたことから、抽象的な概念である「MVC」の考え方に馴染みがありました。しかし、Pythonではよく似た概念として「MTV」という概念が使われており、初めてDjangoに触れる身としては少し違和感がありました。
　今回は、Djangoの抽象的な概念である「MTV」と、Railsなどで用いられる「MVC」の比較を行いその違いについて解説しようと思います。

### 概要
- MVCとは？
- MTVとは？
- RailsとDjangoの違い
## MVCとは？
　MVCとは、フレームワーク内の処理を大きく<b>「Model」「View」「Controller」</b>の3つの概念に整理したものとなります。主に Laravel, Railsなどといったフレームワークで使われています。これだけだと意味が伝わらないと思うのでこの3つの概念について掘り下げていこうと思います。
### Model
　モデル（Model）はアプリケーションの処理やデータを取り扱う部分となります。後述するコントローラの指示によって、<b>データベースから必要な情報を取得したり、逆にデータの登録や更新、削除</b>などをしたりします。Railsだと「モデル名.rb」のファイルが該当します。

### View
　ビュー（View）は、Webアプリにおけるコンテンツの表示を行う部分を指します。今見ているこのQiitaの画面のViewに該当します。コントローラやモデルから取得した情報を基にコンテンツの表示をおこないます。

### Controller
　コントローラ(Controller)は、送られてきたリクエストに応じて、表示するビューを指定したり、ビューに渡すデータの取得をモデルに依頼したりする部分になります。つまりはWebアプリケーションにおける<b>「司令塔」</b>に該当する部分であり、アプリケーションの動きやデータを定義します。

## MTVとは？
　MTVは前述のMVCのように、webアプリケーションにおける処理を「Model」「Template」「View」に分類したものとなります。主にDjangoで使われる考え方になります。コントローラ以外は、MVCとよく似ているように感じられますが、言葉の意味に若干違いがあるのでそこを中心にそれぞれ詳しく述べていきます。
### Model
　モデルはMVCの概念と一番似通っており、webアプリのデータを取り扱う部分となります。データベースとやり取りを行い、データの作成、更新、削除などを行います。
### Template
　テンプレートはMVCの概念でいうと「View」に似ており、指示に応じてHTMLファイルを作成する部分となります。主にアプリの表示に関わる箇所を担います。
### View
　ビューは、モデルから取得してきた情報を取得しテンプレートに渡す部分になります。処理内容としてはMVCの「Controller」に似ていますが、ルーティングに応じて表示するページを決定する機能は<b>URLディスパッチャ</b>という部分が担います。
　つまりMTVにおけるビューはコントローラの<b>「どんなデータを表示させるか」という機能に特化している部分</b>といえ、URLディスパッチャとの連携をなすことでMVCのコントローラのような役割をする部分といえます。

## 両者の違い
　MVCとMTVの違いはMTVのテンプレートとビューによく表れています。Djangoのテンプレートでは、<b>モデルから直接情報を取ってくることができません。テンプレートはただページの内容を返す（表示する）だけの部分でページの振る舞い等はビューで記述します。</b>ここがRailsなどのビューとの大きな違いとなります。「どのような振る舞いをさせるか」などの処理の分業をMVCよりも更に細かく定義することで、アプリの設計や保守、開発をやりやすくしようとしたのがMTVという考え方であると言えます。
PostgreSQLでの、いわゆる'upsert'について

# はじめに

　データベース操作していると、データ追加しようとしたときに主キーがすでに存在した場合にはデータの更新に切り替えたいってとき、ありますよね。
　そういうのを「upsert」って呼んでて、例えばMySQL 5.6では「[13\.2\.5\.3 INSERT \.\.\. ON DUPLICATE KEY UPDATE 構文](https://dev.mysql.com/doc/refman/5.6/ja/insert-on-duplicate.html)」として用意されていて便利そうだなって思っておりましたが、調べてみるとPostgreSQLにも類似の機能があることに気づきましたので、メモしておきます。

# INSERT ～ ON CONFLICT 構文

　「[INSERT](https://www.postgresql.jp/document/13/html/sql-insert.html)」に拠ると、

> ON CONFLICT [ conflict_target ] conflict_action
> 
> ここでconflict_targetは以下のいずれかです。
> 
>     ( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ]
>     ON CONSTRAINT constraint_name
> 
> またconflict_actionは以下のいずれかです。
> 
>     DO NOTHING
>     DO UPDATE SET { column_name = { expression | DEFAULT } |
>                     ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
>                     ( column_name [, ...] ) = ( sub-SELECT )
>                   } [, ...]
>               [ WHERE condition ]

　少々難しく見えますが、割りと融通を利かせた仕組みであることがわかると思います。

## conflict_target : 競合したとみなす条件

　ON CONSTRAINT constraint_name の方はわかりやすいですよね、主キーやユニークキー、NOT NULL、CHECKなどカラムに設けた「制約」につけた名称を指定するときに使います。
　もう一方の表現は、この場で条件をカラム名やカラム名を伴った式で表現するものになります。
　単にカラム名を列挙する、式インデックスとして定義できる式で記述するということになります。
　CREATE INDEXで与えられる式が使えるようです。

## conflict_action : 競合した時どうするか

　DO NOTHING は、競合しても何もしない、行の挿入をしないというものです。
　DO UPDATE は代替の動作として、挿入されようとしていた行と競合する既存の行を更新するものです。　この動作が、いわゆる'upsert'になります。

# 例（ドキュメントからピックアップ）

　ドキュメントから ON CONFLICTに関係するサンプルをピックアップします。

```sql
INSERT INTO distributors (did, dname)
    VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
    ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
```

　didが競合した時、更新する動作ですが、《元々挿入されようとしていた値を参照するために、特別なEXCLUDEDテーブルが使用されている》ところが注目です。

```sql
-- 特定の郵便番号については既存の販売店を更新しません
INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
    ON CONFLICT (did) DO UPDATE
    SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
    WHERE d.zipcode <> '21201';
```

　この例では、挿入されようとしていた値を参照するためのEXCLUDEDと、現在の値を参照するdistributorsのエイリアスdが使われているところに注目です。　新しいdnameと従来のdnameを文字列連結で合成して更新しているわけです。
　また、WHERE句により、特定のzipcode以外のときにのみ更新する動作になっているところも注目です。

# さいごに

　ON CONFLICT句のおかげで柔軟な競合時の動作を指定できるのは便利ですね。　実際に使ってみたいものです。
.NET CLI コマンド

## donet 情報/バージョンを確認する

```cmd
dotnet --version
```

```cmd
dotnet --info
```

参考：[https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet](https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet)

## ソリューションを作成する

```cmd
dotnet new sln
```

```cmd
dotnet new sln --name <OUTPUT_NAME>
```

参考：[https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new](https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new)

## プロジェクトを作成する

```cmd
dotnet new console -n <OUTPUT_NAME> -o <OUTPUT_DIRECTORY>
```

参考：[https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new](https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new)

## プロジェクトをソリューションに追加する

```cmd
dotnet sln add <PROJECT_PATH>
```

参考：[https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-sln#add](https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-sln#add)

## プロジェクトにNugetパッケージを追加する

```cmd
dotnet add package <PACKAGE_NAME>
```

参考：[https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-add-package](https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-add-package)
window.alert の文字列をコピペしたい

# 目的

海外のサイトをブラウジングしていたときに alert でメッセージが出た。

...読めない。

...普通ならコピペで Google 翻訳するが、alert の文字列は選択できずコピーができない。。少なくとも自分のブラウザでは。

英語ならまだしも、他の言語だと書くこともできない。
コピーできるようにしたい。

# やったこと

開発者ツールで `window.alert` を上書きした。js って便利。

```js
window.alert = function(message) { console.log(message); }
```

コンソールに文字列が出たので無事にコピペできた。

# ドキュメント

https://developer.mozilla.org/ja/docs/Web/API/Window/alert
Azure ADのカスタムドメインを利用する一番簡単な方法

# 動機
Azureの検証用のテナントを保有しているのですが、ドメイン名が乱数で作られているようで非常にダサいので変更したくなりカスタムドメイン設定をしてみることにしました。

# 手順
## Azure上でドメインの購入
実はAzure上でドメインを購入することができます。リソース名としてはApp Serviceドメインというものになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/10a02972-1b41-7ef6-51c9-287a389d795e.png)

連絡先情報も記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/27e8d934-07a1-2ffd-a36f-612727badc0d.png)

[確認と作成]へ進み、リソースを作成します。作成が完了されると、App ServiceドメインとDNSゾーンが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/98fd5789-10a8-38d2-ab31-285a7563332c.png)

## Azure AD上でカスタムドメインの設定
Azure ADのカスタムドメインのメニューからカスタムドメインを追加できます。デフォルトでは、最初に契約をしたユーザ名等でドメインが作られてしまっているかと思います。ここに複数のカスタムドメインを追加して可視性を上げていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/0a65e464-02a8-5a9a-a02a-a388e7d5555e.png)

登録したいドメイン名で追加しようとするとレコードに関する情報が確認できます。このドメイン名が自分の保有しているもので、カスタムドメイン名として使用できるということを[確認]する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/fb9e9fd0-ef2a-68a8-a495-0eed808c5eb8.png)
作成した段階だと[未確認]という状態になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/308a5eac-01db-5293-b7d6-2af9954b90c8.png)


そのためにこの情報をAzure DNSゾーン側に登録していきます。

## Azure DNSゾーン側の設定
AppServiceドメインと同時に作成されたDNSゾーンのリソースを開き、TXTレコードセットを登録します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/d532b909-1642-842a-d658-607b83300654.png)

## Azure AD カスタムドメインの[確認]
Azure AD側の画面に戻り、未確認となっているドメイン名をクリック、[確認]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/d29dad8d-7d28-3fa0-1ac2-f744d0425740.png)

確認済みとなれば成功です。そのテナントのドメインとして利用できるようになります。必要に応じてプライマリに設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/9eeab2e7-1c6a-3ad8-72e8-d1432da7a6cf.png)

## UPNの変更
必要に応じて既存ユーザのUPNを変更します。xxxx.onmicrosoft.comはダサい(会社として見てもらえない)のでカスタムドメインに変更しておくのが吉だと思います(笑)
Azure AD->ユーザから、それぞれのUPNを編集します。xxxx.onmicrosoft.com(規定)もしくはカスタムドメインとして登録したもの以外を使おうとすると怒られるので安心です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/11f08dfc-3ed4-70da-cbf9-1328433f7752.png)

# まとめ
といったところで大方流れはご説明できたかと思います。Azure上でドメインを買えてしまうのはかなりシームレスで管理も非常に楽そうだという印象です。備忘録的な殴り書きですがどなたかの役に立てば幸いです！
【IBM Security Verify】 拡張ルール（Advanced Rule）を使って最終ログイン日（lastLogin）を取得する

# はじめに
IBM Security Verifyの拡張ルールを使って、最終ログイン日(lastLogin)のパラメータを取得してみました。
拡張ルールは、単一行の式言語である Google の [Common Expression Language](https://github.com/google/cel-spec) に基づいています

拡張ルールを利用すると以下のようなことができます。
```
この種類の属性は、属性を追加または変換するために使用できます。
コード・エディターを使用して関数および条件を適用します。
```
https://www.ibm.com/docs/ja/security-verify?topic=attributes-attribute-functions

# 最終ログイン日(lastLogin)を取得してみる

属性を追加し、拡張ルールを選択します。
![qiita (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/35da1273-3438-aaca-c201-93a0aebbd0bb.png)

属性名に任意の名前を設定します。
![qiita (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e5b01cf6-7f66-f17d-ceba-18f64f4b6b88.png)

カスタムルールを使って属性値を計算します。
- テスト内容欄に自分の属性値があります。
- 「テストの実行」ボタンをクリックするとテストができます。
- テスト結果は、右側の結果欄で確認できます。



```
条件に鍵括弧をつかっているのは、記号が含まれているためです。
user["urn:ietf:params:scim:schemas:extension:ibm:2.0:User"].lastLogin


記号など含まれない属性は、ドット（.）でつなげて値を取得できます。
user.name.givenName
```

![qiita (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/5fe4fbac-7e84-d522-00c6-91977823b292.png)


# 最後に
今回は、拡張ルール（Advanced Rule）について紹介しました。
アクセスポリシーと組み合わせて、最後のログインが1週間前の場合に、MFAを要求するといった条件も構成できます。

アクセスポリシーで利用する場合は、戻り値がTrue or False の条件になるように拡張ルールを用意しておくと使いやすいです。
草を生やすためのコミットなんか今すぐに辞めてしまえ

# 草を毎日生やすのはとても見栄えがいいですよね

GitHubのプロフィール欄、緑や灰色のマスが沢山並んでいますね。
あれはその日のコミット数（issue作成、PR作成、defaultブランチへのpush数等）を緑の濃さで表しています。
1コミット以上であれば薄い緑、コミット数に応じて徐々に濃い緑。
また、コミットをしなかった日は灰色です。

あの欄を緑色にしていくことを「草を生やす」と呼び、草を生やす活動については記事が多く投稿されていることは皆様ご存知だと思います。
GitHub緑化活動については、「**社内勉強会での登壇をお願いされて、評価が上がったりとかあるかも**」とか、「**見栄えが良くなれば仕事を探しやすくなるかもグヘヘ**」みたいなものがメリットとしてはあったりするかもしれません。

しかし。

# 見栄えのためにわざわざ毎日クソコミットするのはマジで無駄でただの徒労

です。

今すぐ辞めましょう。

# ある男の話

## プロローグ
誰とは言いませんが、上で挙げたような不純な目的で毎日コミットを続けた男が居ました。

その男はなるべくコードを書きたいとは思いつつも、時間が取れなかったり、その日のうちにdefaultブランチへのプッシュが出来るまでの作業が終わらなかったりする事がありました。

<font color="orange">「まずい、今日の草が生えない。」</font>
<font color="orange">「そうだ、草を生やすだけならこうすればいいじゃないか」</font>

彼は適当なタイトルでissueを立て、即座にcloseしました。

するとどうでしょう。
その日のコミット数が1になりました。

## 彼は変わってしまいました

<font color="orange">「今日ちょっと疲れたな」</font>
<font color="orange">「コード書くの面倒だなぁ」ﾊﾟｽﾞﾄﾞﾗ ｽｲｽｲ</font>
<font color="orange">「適当にissue立ててcloseしよ」</font>

1コミット。

**...**

<font color="orange">「明日は忙しいから、今日のうちにコード書いてPR（プルリクエスト）作ろう」</font>
**次の日**
<font color="orange">「マージっと。」</font>

1コミット。

<font color="orange">「毎日コミットなんてラクチンだなぁ」</font>


## そんなある日

**午後六時**
<font color="orange">「今日も疲れたなぁ」</font>
<font color="orange">「ちょっと仮眠取って、起きたらまた適当にissue立てよう」</font>

**...**

**？？？時**
<font color="orange">「よく寝た、さて今日のコミットを......」</font>

<font color="red">**時計「00:15です」**</font>
<font color="orange">「」</font>


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/b2b33b13-f446-3a58-ed79-be6aa00b53d7.png)
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/ce6128a2-8c0a-ae80-7f46-740c1aa042b7.jpeg)

## 一日一（クソ）コミット生活についに幕が下りる

大慌てでコミットを行うも、日が変わってしまった以上、草は生えません。

彼は泣き叫びました。

クソコミットであろうと、毎日積み重ねて作ってきた芝生だったのです。

彼はＳＮＳで悲鳴をあげました。

やってしまった。今まで行ってきたことを無駄にしてしまった、と。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/2bea3c04-1685-2d66-281c-53caaaeaee6d.png)

**運営者ギルド**の方からは、このような返信をいただけました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/160b77de-ab5f-5785-05de-c5a6e7e100b9.png)

・・・！？

## 過去の草は”生やせる”

[過去日付でGithubの草を生やす](https://zatoima.github.io/blog-github-contributions-before-date.html)
こんなんありました。

適当なリポジトリでやってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/91d2339b-9247-47c2-6f57-8b126aa4b1e5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/b95d3ba1-72c2-d6ed-3288-4a3d4225b450.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/3ba14444-bfc8-2592-44a0-a9657c62be0f.png)

生えた！！！！！

## 男は考える

<font color="orange">「えっ」</font>
<font color="orange">「後からでも生やせるんなら」</font>
<font color="orange">「別に毎日草を生やすのって意味なくない？」</font>

**そしてタイトル。**

# 草を生やすためのコミットなんか今すぐに辞めてしまえ

これは草を生やすことや、毎日コミットを行う事が無駄というわけではないのです。
**草を生やすために**クソコミットをすることが無駄だという事です。

そもそも、毎日コミットを行う事についての記事は、**毎日コードを書くこと**のメリットに触れているのであり、その副産物として草が生えているだけなのです。
草を生やすためのクソコミットをしているようでは、まさしく「**目的と手段が逆転**」しています。
だって草なんて後から生やせるのですから。

むしろ、「今日のコミットは何にしようかなぁ」と毎日考えなければいけない分デメリットです。
脳のリソースをそんな訳のわからない事に割くべきではありません。
そんなん考える暇があったら技術書読んだり、コード書いたりアーキテクチャの勉強してる方が百倍有意義です。

以上、自分への戒めでした。
WireGuardでVPN接続

# 事前準備
サーバとクライアント両方で以下のコマンドを実行する。
```shell
root# apt install -y wireguard
```
# 設定方法
以下にWireGuardのサーバとクライアント設定方法を示す。
## Serverの設定

### 1. サーバ用秘密鍵の作成
```shell
root# wg genkey| tee /etc/wireguard/server.key
0I62zaLHBLbTNn1PFkarLyzkL11cuCPBuTvTU7/sVWM=
```
### 2. サーバ用公開鍵の作成
```shell
root# cat /etc/wireguard/server.key |wg pubkey | tee /etc/wireguard/server.pub
6IPfYoRdPAg1iKSYF3bAiqbuVofWayIPCMHhcJdw7WI=
```
### 3. クライアント用秘密鍵の作成
```shell
root# wg genkey | tee /etc/wireguard/client.key
qPaLzgFaCsj9o2nR9WZOxOv1NUA/WbuIN3doSDI69nc=
```
### 4. クライアント用公開鍵の作成
```shell
root# cat /etc/wireguard/client.key |wg pubkey |tee /etc/wireguard/client.pub
1W5we9rb1WnnaRYCKKOBOA/rWWo/71r5I4J9eDTUTzY=
```
### 5. コンフィグの作成
```shell
root# cat <<EOF > /etc/wireguard/wg0.conf
[Interface]
# 1.で生成したサーバー用秘密鍵を指定
PrivateKey = 0I62zaLHBLbTNn1PFkarLyzkL11cuCPBuTvTU7/sVWM=
# 使用するIPアドレス
Address = 10.0.0.1
# サーバで使用するポート
ListenPort = 51820

[Peer]
# 4.で生成したクライアント用公開鍵を指定
PublicKey = 1W5we9rb1WnnaRYCKKOBOA/rWWo/71r5I4J9eDTUTzY=
# 接続を許可するIPアドレス
AllowedIPs = 10.0.0.2
EOF
```

### 6. WireGuardの起動
```shel
root# systemctl enable wg-quick@wg0
root# systemctl start wg-quick@wg0
```

## Clientの設定
```shell
root# cat << EOF >/etc/wireguard/wg0.conf
[Interface]
# 3.で生成したクライアント用秘密鍵の指定
PrivateKey = qPaLzgFaCsj9o2nR9WZOxOv1NUA/WbuIN3doSDI69nc=
# 使用するIPアドレス
Address = 10.0.0.2

[Peer]
# 2.で生成したサーバ用公開鍵の指定
PublicKey = 6IPfYoRdPAg1iKSYF3bAiqbuVofWayIPCMHhcJdw7WI=
# 接続するサーバのIPアドレスとポート指定
EndPoint = 192.168.1.1:51820
# VPNを通して接続するIPアドレスやネットワークの指定
AllowedIPs = 10.0.0.0/24
EOF

root# wg-quick up wg0
```

# 接続確認
クライアントからサーバにWireGuard越しで接続できるか確認
```shell
root# ping -c 4 10.0.0.1
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.247 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.415 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.400 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.434 ms

--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3080ms
rtt min/avg/max/mdev = 0.247/0.374/0.434/0.074 ms
```

# 最後に
WireGuardサーバーのGUIではクライアントのconfigを自動生成したりQRコードからconfigのダウンロードが行えたできる。WireGuardはスマホやPCでも簡単にクライアントにすることができて、特定のネットワークのみVPN接続も簡単にできるのでSoftEtherより使い勝手がよさそう。

# 参考サイト
https://www.server-world.info/query?os=Ubuntu_20.04&p=wireguard&f=1

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0614
[iOS]一度サポートしたデバイスのサポートを外すことはできない

すでにiPadとiPhoneをサポートしていたアプリについて、iPadのサポートを外して、App Store Connectにアップロードしようとしたところ以下のエラーが出ました。

```
*** Error: This bundle does not support one or more of the devices supported by the previous app version. Your app update must continue to support all devices previously supported. You declare supported devices in Xcode with the Targeted Device Family build setting. Refer to QA1623 for additional information: https://developer.apple.com/library/ios/#qa/qa1623/_index.html App Store operation failed. (1091)
 {
    NSLocalizedDescription = "This bundle does not support one or more of the devices supported by the previous app version. Your app update must continue to support all devices previously supported. You declare supported devices in Xcode with the Targeted Device Family build setting. Refer to QA1623 for additional information: https://developer.apple.com/library/ios/#qa/qa1623/_index.html";
    NSLocalizedFailureReason = "App Store operation failed.";
    NSLocalizedRecoverySuggestion = "This bundle does not support one or more of the devices supported by the previous app version. Your app update must continue to support all devices previously supported. You declare supported devices in Xcode with the Targeted Device Family build setting. Refer to QA1623 for additional information: https://developer.apple.com/library/ios/#qa/qa1623/_index.html";
}
```
一度サポートしたデバイスのサポートを外すことはできないようです。

ドキュメント https://developer.apple.com/library/archive/qa/qa1623/_index.html を見てみると、以下のような対策が書かれています。

- 全く新しいアプリとして開発する（新しいアプリはiPhone専用とし、iPadは外す、ということでしょう）
- 要求iOSバージョンをあげることで、古い端末へのサポートを外す（しかしiPadシリーズは新しいiOSバージョンにも対応していくので、今回はこれでは対策にならなそう）
- 諦めて、以前と同様の端末をサポートし続ける

>  Q: Why am I getting an error about supporting previous devices when I upload an update of my app?
A: iTunes Connect does not allow uploading an updated version of an app when the update runs on fewer devices than the version of the app currently in the App Store. This is by design.
An update to an app must work for every customer who has already purchased the app, and is running a current version of iOS.
Developers who wish to issue updates, but remove device support, have three choices:
Fix their app so that it can work on the devices they originally set out to support. See Supporting All Devices for details.
Target a newer version of iOS that requires a newer device. See Targeting the Latest iOS for details.
Remove their app from the store, and upload the new app with a different bundle ID. See Replacing Your App in the Store for details.
【MT7】複数行テキストで改行タグのみ適用させる

## はじめに
**MovableType7**
複数行テキストで文章を入力する際によく使うモディファイアです。


## やりたいこと
・余計なHTMLのタグが入っている場合は除外したい。
・改行は適用させたい。

## 使用するモディファイア
``` 
remove_html="1" nl2br="1"
```

## 使用例
### コンテンツタイプで使用する場合
``` 
<mt:ContentField content_field="説明文4">
　<p class="c-text01">
　　<$mt:ContentFieldValue remove_html="1" nl2br="1"$>
　</p>
</mt:ContentField>
```

### 記事の本文に使う場合
```
<mt:EntryBody remove_html="1" nl2br="1">
```

## 入力画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/e2efd4d8-6060-224f-72a4-c796d8d74cc7.png)
フォーマットはデフォルトの「なし」。
HTMLタグを使わずに文章を入力しています。

## 出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/4b2190b2-1a85-6e63-b767-6b2a8ddd283f.png)
改行が適用されています。

## 説明
・**remove_html**：1を指定すると、すべてのHTMLタグを除去します。
たとえば、 Nogizaka\<br>Sakurazaka は改行されずに Nogizaka Sakurazaka と変換されます。

・**nl2br**：1を指定すると、値に含まれる改行をbrタグに変換します。


## 参考サイト
・[nl2br | MovableType公式リファレンス](https://www.movabletype.jp/documentation/appendices/modifiers/nl2br.html)

・[remove_html  | MovableType公式リファレンス](https://www.movabletype.jp/documentation/appendices/modifiers/remove_html.html)

・[実務で役立つMovable Typeのグローバルモディファイア15選 | tadabi](https://tadabi.tokyo/2021/mt-modifier/)

・[テキスト複数行フィールドに入力された改行のみを出力する方法 | CMS NOTE](https://cms-note.com/movabletype/mt_br.html)
【Xcode】突然シュミレーターでビルドできなくなった

# 問題
環境
- iOS14.2+
- Xcode13.0+

発生条件(私の場合)
- SPMでインストール
- シュミレーターだけでビルドできない
- Alamofireで発生

# エラー文
```
Could not find module 'Alamofire' for target 'x86_64-apple-ios-simulator'; found: arm64-apple-ios-simulator, at: /Users/XXXXXXXXXX/Library/Developer/Xcode/DerivedData/XXXXXXXXX/Build/Products/Debug-iphonesimulator/XXXXXXXXXX.swiftmodule
```

# 解決策
Build Settingsで`Excluded Architectures`と検索します。
<img alt="スクリーンショット 2022-05-31 12 24 58" src="https://user-images.githubusercontent.com/84154073/171087402-1bf4f761-127d-49aa-9efe-be461c4ee1ab.png">

Debugを`Any SDK`　→ `Any iOS`に変更します。
<img alt="スクリーンショット 2022-05-31 12 34 35" src="https://user-images.githubusercontent.com/84154073/171087684-d77fb12d-6a3e-4895-976a-3e41be6cd0a7.png">

`arm64`をダブルタップして編集画面を開きます。
`x86_64`を追加します。
<img alt="スクリーンショット 2022-05-31 12 36 49" src="https://user-images.githubusercontent.com/84154073/171087953-34afa7a9-402a-452a-be7e-cadb9beb09f4.png">

# おわり
コード以外のエラーは怖いです。
🔰【初学者用】本当に初歩の初歩の初歩的なよく使うHTMLタグをまとめてみた。

# はじめに
毎日Qiita投稿5日目です。
今回は初学者が最低限覚えておくべき、本当に初歩の初歩の初歩的なHTMLタグをまとめていきます。

# 基本構造、head内
| タグ | 使用用途 |
|:-|:-|
| html  | HTML文書であることを表す。  |
| head  | 基本的にHTMLのヘッダ部分に記載。中の記述はブラウザには表示されない。この中にページのタイトルやcssファイルリンクなどを記載。 |
| meta  | 言語や説明文などのページ情報を記載。初学の頃は主にUTF-8のを記述するイメージ。  |
| title  | ページのタイトルブラウザーのタブにここの記載が表示される。  |
| link  | 参照する外部ファイル主にcssファイルを読み込む。  |
| body  | HTMLのコンテンツ部分。この中の記述がブラウザーに表示される。  |

# コンテンツ内
| タグ | 使用用途 |
|:-|:-|
| h1〜h6  | 見出し。基本的には数字順位記述していく。  |
| p  | 段落。 |
| img  | 画像。srcで画像取得。 |
| a  | リンク。hrefでリンク取得 。 |
| ul  | 箇条書きリスト。  |
| ol  | 番号付き箇条書きリスト。  |
| li  | リストの各項目。  |
| br  | 改行。  |
| strong  | 重要な要素。太字で表示される。  |
| small  | 著作権や法的表記。  |
| span  | インライン要素。CSSで一部表示を変えたいときなどに使用。  |
| script  | javascriptを記述する際に使用する。  |

# 表（テーブル）
| タグ | 使用用途 |
|:-|:-|
| table  | 表（テーブル）全体。  |
| tr  | 表の１行。  |
| th  | 表の見出しとなるセルを作成。  |
| td  | 表のデータとなるセルを作成。  |

# フォーム
| タグ | 使用用途 |
|:-:|:-:|
| form  | フォームを作成する。  |
| `<input type="text">`  | １行テキスト入力欄。  |
|` <input type="radio"> ` | 選択項目のうち１つだけ選択可能なラジオボタン  |
| `<input type="checkbox"> ` | 複数選択可能なチェックボックス。  |
| `<input type="submit">`  | 送信ボタン。  |
| select  | セレクトボックス。  |
| textarea  | 複数行入力可能なテキスト入力欄。  |
| label  | ファームのラベル。フォームの項目と名前を関連付ける事ができる。  |

# ブロック要素
| タグ | 使用用途 |
|:-:|:-:|
| header  | ページ上部の要素。  |
| nav  | メインのナビゲーション。  |
| article  | ページの記事部分。  |
| section  | 意味や機能のひとまとまり。  |
| main  | ページのメインコンテンツ。  |
| aside  | 補足情報や、メインコンテンツとは関連性が低い部分。  |
| footer  | ページ下部の要素。©やSNSリンクなど。  |
| div  | ブロック要素。  |

# 終わりに
今回はHTMLの基本的なタグをまとめてみました！
初学者の方がこれを全て**一気に覚えるのは大変**です。暗記教科のよう覚える必要はなく、コード書いてたら覚えていった。使いながら覚えていくという形が一番の近道かなと思います！
だからコードに触れる時間は多く取りたいですね。

※プログラミングを始めてまだ月日も浅い初学者が投稿しています。誤字脱字等ありましたら申し訳ないです。何か間違いがあればご指摘いただけると助かります。
Androidのgradle versionを上げたら起動しなくなった

## Gradle versionをポチポチと最新版に変更

### gradle-7.0.2-all.zip -> gradle-7.4.2-bin.zip

distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
-> distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip

### gradle:7.0.4 -> gradle:7.2.1
classpath 'com.android.tools.build:gradle:7.0.4'
-> classpath 'com.android.tools.build:gradle:7.2.1'

## 上げて動かそうとしたら。。。起動せず。

### Non-fatal Exception: java.lang.RuntimeExceptionMissing type parameter.
```
Non-fatal Exception: java.lang.RuntimeException
Missing type parameter.
com.google.gson.reflect.TypeToken.getSuperclassTypeParameter (TypeToken.java:84)
com.google.gson.reflect.TypeToken.<init> (TypeToken.java:62)
```

## 解決方法
proguard-rules.proに下記を追加

```
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
```


まだ　openだけど解決したIssues
https://github.com/google/gson/issues/2069
OpenBrushでSmartContract開発

# OpenBrushとは

ink!のための、スマートコントラクト開発ライブラリ群です。
EthereumのOpenZipppelinのように、コードの再利用をテーマとしています。

(カンファレンス)
https://hopin.com/events/wasm-conference-2022

https://www.crowdcast.io/e/substrate-seminar-2/register?session=10

(動画)
https://www.youtube.com/watch?v=I5OFGNVvzOc

(本家)
https://openbrush.io/

# versions

1.8.0 3days ago
https://crates.io/crates/brush_contracts_derive/versions

# どのような機能があるか？
https://github.com/Supercolony-net/openbrush-contracts
https://lib.rs/crates/brush_contracts_derive

PSP22 - Fungible Token (ERC20 equivalent) with extensions
PSP34 - Non-Fungible Token (ERC721 equivalent) with extensions
Multi-Token ERC1155 equivalent with extensions
Ownable Restrict access to action for non-owners
Access Control Define set of roles and restrict access to action by roles
Reentrancy guard Prevent reentrant calls to a function
Pausable Pause/Unpause the contract to disable/enable some operations
Timelock Controller Execute transactions with some delay
Payment Splitter Split amount of native tokens between participants

# WASMのPSPとは？

PSP-Polkadot標準Polkadot Standards Proposals（PSP）と呼ばれます。
ERCライクなものと考えればよさそうです。

https://docs.edgeware.wiki/development/develop/smart-contracts/wasm-smart-contracts/tutorials/wasm-psp22/psp

https://github.com/w3f/PSPs

# ためしにpayment splitterを使って実装してみる

#[brush::contract]

use brush::contracts::payment_splitter::*;

https://github.com/ChaosDAO-org/ape-strapper-wasm/blob/5691f9876b4f38346bc9d3c628a5f05af68b843c/ape_strapper_wasm/lib.rs


```
$ cargo contract new own_paymenet_splitter_demo
$ cargo +nightly contract buil


ERROR: Mismatching versions of `parity-scale-codec` were found!
Please ensure that your contract and your ink! dependencies use a compatible version of this package.

// parity-scale-codecのversion => 3　に変更
// scale-infoのversion => 2 に変更
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"], optional = true }


```
最も簡単なFlutterのパスの通し方

# Flutterのパスを通すときに惑わされた結果
Macbookを新しくしまして、ついでにユーザーアカウントについても色々整理した結果
設定のやり直しが発生したんですが、その中でも「Flutterのパスを通すのどうやったっけ？」から見事に堂々巡りをしてきました。（いろんな記事がありますからね）

## 簡単なパスの通し方
完結にいうとPATHを通すにはこれだけやればいい話でした。

```:cmd
export PATH="$PATH:[flutterフォルダが格納されているディレクトリ]/flutter/bin"
```
下記は私が惑わされた部分になるんですが、ターミナルの種類によって云々の件
（結局いらなかったんですが一応書き出します）

### bashの場合
```:cmd
vim .bash_profile
```
```:cmd
echo 'export PATH="$PATH:[PATH_TO_FLUTTER]/flutter/bin"' >> ~/.bash_profile
source ~/.bash_profile
```

### zshの場合
```:cmd
vim .zshrc
```
```:cmd
echo 'export PATH="$PATH:[PATH_TO_FLUTTER]/flutter/bin"' >> ~/.zshrc
source ~/.zshrc
逆にこれやろうとすると沼ってしまったんで、もし同じように沼った人がいたら一旦シンプルなPATHの通し方に変更して挑戦してみてください。
```
## パスが通ったかの確認
パスが通ったかどうかはwhich flutterでファイルの場所を見ることができます。

```:cmd
MacBook-Pro:~ waaaco$ which flutter
/Users/ユーザ名/old/flutter/bin/flutter
flutter doctorをやってみる
パスが通ったところでいよいよflutterコマンドの登場です。

成功するとflutter doctorコマンドでこんな感じに出てくれます。

```:cmd
MacBook-Pro:~ waaaco$ flutter doctor
╔════════════════════════════════════════════════════════════════════════════╗
║ A new version of Flutter is available!                                     ║
║                                                                            ║
║ To update to the latest version, run "flutter upgrade".                    ║
╚════════════════════════════════════════════════════════════════════════════╝

＜中略＞
Running "flutter pub get" in flutter_tools...                       9.9s
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.1, on macOS 12.4 21F79 darwin-x64, locale
    ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK version
    32.1.0-rc1)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for
      more details.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[!] Android Studio
    ✗ Unable to find bundled Java version.
[!] Android Studio
    ✗ Unable to find bundled Java version.
[✓] VS Code (version 1.66.2)
[✓] Connected device (1 available)
[✓] HTTP Host Availability

! Doctor found issues in 3 categories.
```

あとはこんな感じにFlutterの足りない設定を直していく作業になるので、この回はここまでとさせていただきます。
document.getElementByIdのReact版って何？

業務で元々はJavaScriptやjQueryを書いていましたが
新しくReact+TypeScriptで書くことになり表題の件で躓きました。
以下実装時に使用したものと解説を書きます。

## ズバリ使うのは、Ref！！！

RefはDOM操作に役立つReactのAPIです。Hooksで追加されたのがuseRefになります。
基本的にReactでDOM操作を行おうと思ったとき、ピュアJavaScriptのdocument.getElementById、document.querySelector系のAPIは使用できません。というよりもidを使用すること自体がNGだそうです。
idをもつということはReactが最終的なbundle.jsとして吐き出した際に、idが重複したものが出力される可能性があるためです。
そういったことからidの使用はアンチパターンといえそうです。
そこでReactでは代替えとしてref属性からDOMを参照し、操作を行います。

## 例. フォームに入力された値をボタンタグのクリックイベントで取得


```react: 例
import React, { useRef, MouseEvent } from 'react'; // ①useRef追加

const personZipcode = () => {
    const textRef = useRef<HTMLInputElement>(null);　　// ②nullで初期化
    const onClickEvent = (e: MouseEvent<HTMLButtonElement>) => {
        if (!textRef.current) return;　// ④nullでないことを確かめる
        let zipCode = textRef.current.value;　// ⑤入力値取得
        console.log(zipCode);
    }

    return (
        <>
            <p>
                <label>
                    〒
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　{/* ③ref属性追加 */}
                    <input type='text' name='personZipcode' placeholder='例）1030015' ref={textRef}/>
                </label>
                <button type='button' onClick={onClickEvent}/>
            </p>
        </>
    )
}

export default personZipcode;
```
## 解説

①useRef追加
②refを定義し、初期値にnullを持たせる。これはレンダリングする前の初期値
③ref属性追加
④useRefにnullを渡してHTMLInputElementで型づけると、
　そのcurrentプロパティ(Input)はHTMLInputElement | nullのユニオン型で推論されます。
　すると、要素の参照として扱う前に、必ずnullでないことを確かめなければなりません。
　そうしなければ、「オブジェクトは 'null' である可能性があります。」というエラーが示されてしまいます。
⑤入力値取得

## 備考
今回はrefを使用し、フォームに入力された値を取得しましたが
下記の記事を参考にするとdocument.getElementByIdでも値は取得できます。
https://qiita.com/Sekky0905/items/a88721f2af41050c93f2

## 参考文献

下記サイトが非常にわかりやすく解説されています。
ぜひご一読ください。

・https://ryotarch.com/javascript/react/control-react-dom-with-ref/
・https://qiita.com/FumioNonaka/items/feb2fd5b362f2558acfa
zshのサブコマンド補完を手短に作成する

scoop など、サブコマンドを持っていて、zsh の補完が公式から定義されていないコマンドの補完をささっと作るテンプレートを作った。
ファイル名は補完対象のコマンド名の先頭にアンダースコア`_`を付与した名前にする。
このファイルを `_fpath` の通っているディレクトリに置けばOK。
```shell:_scoop
#cmddef scoop
# ↑補完対象のコマンド名を記述する
function (){
  # 自動で生成される変数。ローカル化しておく
  local context state line
  typeset -A opt_args

  # サブコマンド1つにつき「サブコマンド名:説明文」の行を作る。「:説明文」は省略可能
  # 補完文字列に「:」を使う場合はバックスラッシュでエスケープする
  local subcmd_text=$(cat <<'_EOS'
alias:Manage scoop aliases
bucket:Manage Scoop buckets
cache:Show or clear the download cache
cat:Show content of specified manifest. If available, `bat` will be used to pretty-print the JSON.
checkup:Check for potential problems
cleanup:Cleanup apps by removing old versions
config:Get or set configuration values
create:Create a custom app manifest
depends:List dependencies for an app
download:Download apps in the cache folder and verify hashes
export:Exports (an importable) list of installed apps
help:Show help for a command
hold:Hold an app to disable updates
home:Opens the app homepage
info:Display information about an app
install:Install apps
list:List installed apps
prefix:Returns the path to the specified app
reset:Reset an app to resolve conflicts
search:Search available apps
shim:Manipulate Scoop shims
status:Show status and check for new app versions
unhold:Unhold an app to enable updates
uninstall:Uninstall an app
update:Update apps, or Scoop itself
virustotal:Look for app's hash on virustotal.com
which:Locate a shim/executable (similar to 'which' on Linux)
_EOS
  )
  # 上記で作った「サブコマンド名：説明文」を行区切りで配列に変換する
  local subcmds=("${(@f)subcmd_text}")

  # _arguments コマンド：文脈に応じて補完の振り分けをしたり登録したりするコマンド
  # 補完対象文字列が "-" で始まっていなければ(=非オプションならば)、$state 変数に "subcmd" が代入される
  _arguments : '*::scoop-subcmd:->subcmd' # scoop-subcmd の部分は補完時に表示されるメッセージであり任意の文字に置き換える
  if [[ "$state" == "subcmd" ]]; then
    if (( CURRENT == 1 )); then # 現在の補完が1つ目の単語のとき（CURRENT も自動生成される変数）
      # _descripbe コマンド：配列変数名を指定すればその配列を補完として登録するコマンド
      # 先ほど生成した subcmds 配列変数を補完候補として指定する
      _describe "scoop-subcmd" subcmds  # _describe <description> <array-name>
    else
      # それ以降の補完にはファイル名を補完させる
      _arguments : '*::Files:_files'
      # もしそれ以降の補完を作る場合は自動で生成される配列変数 words を $words[1] を見てサブコマンドを判定して分岐させるとよい
    fi
  fi
}

```
Flutterのパスを通すときに惑わされた結果

# Flutterのパスを通すときに惑わされた結果

Macbookを新しくしまして、ついでにユーザーアカウントについても色々整理した結果
設定のやり直しが発生したんですが、その中でも「Flutterのパスを通すのどうやったっけ？」から見事に堂々巡りをしてきました。（いろんな記事がありますからね）

## 簡単なパスの通し方
完結にいうとPATHを通すにはこれだけやればいい話でした。
```zsh:cmd
export PATH="$PATH:[flutterフォルダが格納されているディレクトリ]/flutter/bin"
```
下記は私が惑わされた部分になるんですが、ターミナルの種類によって云々の件
（結局いらなかったんですが一応書き出します）

### bashの場合
```zsh:cmd
vim .bash_profile
```
### こう対応してねの話
```zsh:cmd
echo 'export PATH="$PATH:[PATH_TO_FLUTTER]/flutter/bin"' >> ~/.bash_profile
source ~/.bash_profile
```

### zshの場合
```zsh:cmd
vim .zshrc
```
### こう対応してねの話
```zsh:cmd
echo 'export PATH="$PATH:[PATH_TO_FLUTTER]/flutter/bin"' >> ~/.zshrc
source ~/.zshrc
```
逆にこれやろうとすると沼ってしまったんで、もし同じように沼った人がいたら一旦シンプルなPATHの通し方に変更して挑戦してみてください。


## パスが通ったかの確認
パスが通ったかどうかはwhich flutterでファイルの場所を見ることができます。
```zsh:cmd
MacBook-Pro:~ urara$ which flutter
/Users/urara/old/flutter/bin/flutter
```

## flutter doctorをやってみる
パスが通ったところでいよいよflutterコマンドの登場です。

成功するとflutter doctorコマンドでこんな感じに出てくれます。
```zsh:cmd
MacBook-Pro:~ urara$ flutter doctor
╔════════════════════════════════════════════════════════════════════════════╗
║ A new version of Flutter is available!                                     ║
║                                                                            ║
║ To update to the latest version, run "flutter upgrade".                    ║
╚════════════════════════════════════════════════════════════════════════════╝

＜中略＞
Running "flutter pub get" in flutter_tools...                       9.9s
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.1, on macOS 12.4 21F79 darwin-x64, locale
    ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK version
    32.1.0-rc1)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for
      more details.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[!] Android Studio
    ✗ Unable to find bundled Java version.
[!] Android Studio
    ✗ Unable to find bundled Java version.
[✓] VS Code (version 1.66.2)
[✓] Connected device (1 available)
[✓] HTTP Host Availability

! Doctor found issues in 3 categories.

```

あとはこんな感じにFlutterの足りない設定を直していく作業になるので、この回はここまでとさせていただきます。
kustomizeでリソースを削除する

# 環境

- Kustomize (v4.5.4)

# QA環境の Deployment を削除する例

`$patch: delete` として、`patchesStrategicMerge` で指定します。

```yaml:delete-deployment.yml
$patch: delete
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-name-to-be-deleted
```

```yaml:kube/overlays/stg/kustomization.yml
patchesStrategicMerge:
- delete-deployment.yml
```
Mongo DB の入れ子構造で $unset

# 前置き
あまり設計に慣れておらず，ややこしい（？）入れ子構造でデータを作ってしまい，データ修正に困ったので，覚え書き．

# DB 構造

```json
[
{
    scores: [
        {
            player_id: "user1"
            point: 10,
            events: [
                {
                    player_id: "user1"
                    id_in_another_collection: "foobar",
                    img_id: "imageimage"
                }
        },
        {
            player_id: "user2"
            point: 30,
            events: [
                {
                    player_id: "user2"
                    id_in_another_collection: "barfoo",
                    img_id: "imageimage2"
                }
                {
                    player_id: "user2"
                    id_in_another_collection: "barfoobar",
                    img_id: "imageimage3"
                }
            ]
        }
    ],
    other_data: "others...",
},
{...},
 ...
]
```

`player_id` が `scores.$.event.$` で被っていることに気付いて，あとで `$unset` しようとして，ハマったお話です．

# 問題のややこしさ
見ての通り，最深部の `player_id` にたどり着くまでに 
`(all_records ->) record -> scores -> score -> events -> event -> player_id`，すなわち，`(array ->) object -> array -> object -> array -> object` というややこしい手順を踏まなければならない...

# 解決策
```js
db.scores.updateMany(
    {"scores.events.player_id": { $exists: true, $not: {$size: 0} }}, 
    {$unset: {"scores.$[].events.$[e].player_id": ""}}, 
    {"arrayFilters": [{"e.player_id": {$ne: null}}]})
```

### 第一引数
`player_id` が空でないレコードを抜き出している．後に `arrayFilters` を適用するので不要かも？

### 第二引数
`$unset` の指定．`player_id` を `unset` します，という意．
`"scores.$[].events.$[e].player_id"` の `$[e]` は identifier と呼ばれているもので，公式ドキュメント[^1] によれば，

> The filtered positional operator $[<identifier>] identifies the array elements that match the arrayFilters conditions for an update operation, e.g. db.collection.updateMany() and db.collection.findAndModify().

すなわち，指定したフィルタにマッチする配列のキーを与えてくれるそうです．

`$[]` は配列の全ての要素，という意味[^2]．

フィルタについては第三引数を参照．

### 第三引数
第二引数で取り上げたフィルタを指定．
`e` は，第二引数において `$[e]` と表記した配列キーが指定しているオブジェクトに対応する（`event.$[e] = e`）．
`"e.player_id" : {$ne: null}` は，配列 `event` の任意の要素 `e` について，`e.player_id` が `null` でなければフィルタに引っかかる，という意味である．
このときに引っかかった `$[e]` （実体は 0, 1 などの配列キー）を第二引数で用いて `$unset` してくれる．

# 参考
[^1]: [$[<identifier&gt;] — MongoDB Manual](https://www.mongodb.com/docs/manual/reference/operator/update/positional-filtered/)
[^2]: [$[] — MongoDB Manual](https://www.mongodb.com/docs/manual/reference/operator/update/positional-all/)