OmniAICreator/Qiita-1.07M huggingface dataset:
AWS GlueでConnectionにフェイルオーバーやロードバランシング機能を持たせたい

## 設定画面からはできない

* AWS Glueの「Connection（接続）」設定で、1つのコネクションに複数のサーバーIPを直接指定し、優先順位や条件（フェイルオーバーやラウンドロビン等）をGlueの設定画面で制御することはできません。

## 代替策

### JDBCのフェイルオーバー機能を利用

接続先がJDBC対応データベース（例：MySQL, PostgreSQL, SQL Server等）の場合、JDBC接続文字列で複数のホストを記述し、ドライバー側のフェイルオーバーやロードバランシング機能を利用できます。

```s
jdbc:mysql://server1,server2,server3/dbname?failOverReadOnly=false&autoReconnect=true
```

### Glueジョブ側で制御

Glueで複数のConnectionを作成し、ETLジョブのスクリプト内で接続先を切り替えるロジックを記述する。
例えば、接続失敗時に別のConnectionを使うようにPython（PySpark）で制御。

```diff
  import sys
  from awsglue.context import GlueContext
  from pyspark.context import SparkContext
  from awsglue.dynamicframe import DynamicFrame
  
  sc = SparkContext()
  glueContext = GlueContext(sc)
  
+ # 接続名リスト（優先順）
+ connections = ["my_connection_primary", "my_connection_secondary"]
  
+ for conn in connections:
+     try:
+         # データソースの読み込み（例：JDBC）
+         datasource = glueContext.create_dynamic_frame.from_options(
+             connection_type="mysql",
+             connection_options={"connectionName": conn, "database": "testdb", "dbtable": "my_table"},
+             transformation_ctx="datasource"
+         )
          print(f"接続成功: {conn}")
          break  # 成功したらループ終了
      except Exception as e:
          print(f"接続失敗: {conn} - {str(e)}")
          continue
  
  # この後、datasourceを使って処理を続行
```


### DNSラウンドロビンやロードバランサーの利用

GlueのConnectionには単一のホスト名しか指定できませんが、そのホスト名に対してDNSラウンドロビンやAWS Network Load Balancerなどを使い、裏で複数IPへの分散やフェイルオーバーを実現する
SQLServerで冗長化の確認

## SSMS (SQL Server Management Studio) で確認する。
 
「Always On」や「可用性グループ」を見るとわかる。

https://www.kacoms.co.jp/column-it-ashita-yakudatsu-20230712/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/2305f430-16f1-4e2d-9f50-7e0f3afae3ba.png)

* 「読み取り可能なセカンダリレプリカ」として構成されていれば、セカンダリに対してSELECT文などの読み取り専用クエリを実行できる。

### クエリで確認

```sql
SELECT
  replica_server_name,
  secondary_role_allow_connections_desc
FROM
  sys.availability_replicas;
```

* secondary_role_allow_connections_descの値が`READ_ONLY`なら、そのセカンダリレプリカは読み取り可能。

### SSMS で確認する場合

1. プライマリレプリカに接続。
1. オブジェクトエクスプローラーで「AlwaysOn 高可用性」→「可用性グループ」を展開。
1. 対象の可用性グループを選択し、「可用性レプリカ」を右クリックして「プロパティ」。
1. 「セカンダリ ロール」の「読み取り可能セカンダリ」欄で、`「はい」`や`「読み取り専用」`などが選択されていれば、そのレプリカは読み取り可能。

画面イメージはいか

```
+ オブジェクトエクスプローラー
  + サーバー名 (SQL Server バージョン)
    + データベース
    + セキュリティ
    + サーバーオブジェクト
    + レプリケーション
    + Always On 高可用性
      + 可用性グループ
        + [グループ名]
          + 可用性データベース
          + 可用性レプリカ
```
IntersectionObserverを使ってFABの挙動をコントロールする【React】

## はじめに
SPAではユーザーのスクロール操作に応じてUIを変えるニーズが多くあり、
私自身も自作しているReactアプリの中で「ある要素が今画面に見えているか」を検知しそれをトリガーにUIを切り替える方法を探していました。
今回、**IntersectionObserver API** を使用しFABの挙動をコントロールする手法をこの記事では紹介します。


## IntersectionObserverとは

* ブラウザ上で要素が**画面内に入っているかどうかを自動で検知**できるAPI
* 見えている・見えていないをトリガーにしてUIを切り替える場面でよく使われる



## ユースケース詳細
![flow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977506/fc1591a2-fb80-4ae8-aed1-41e663dcdd85.jpeg)

SearchFormが**画面からスクロールで消えたら**、代わりにFAB（フローティングボタン）を表示する設計です。

「**ある要素の表示／非表示をトリガーにUIを切り替えたい**」という場面で、IntersectionObserverを使うことができます。



## 実装手順

### 1. フォームを見張る

まず検索フォームに ref を渡せるようにしておきます。
React の Ref を使って書き換えます。

```tsx
import type { RefObject } from 'react';

const searchFormRef = useRef(null);
```


### 2. トリガー対象となるフォーム（SearchForm）を監視対象として指定する

#### ref
特定の要素やコンポーネントを直接参照したいときにrefを使います。
DOMの位置や状態を検知したいときの橋渡しになる考え方です。
今回だとフォームが画面から消えた時がトリガーになるので、SearchFormを監視対象にします。

```tsx
const searchFormRef = useRef(null);
        <SearchForm
           ref={searchFormRef} //このDOM要素を監視対象として指定する
        />
```


### 3. IntersectionObserverで表示状態を監視

次に、SearchFormが画面に見えているかどうかを自動で検知し、状態を更新します。
```tsx
useEffect(() => {
  // IntersectionObserverを新しく作成（entryで監視対象の状態を受け取る）
  const observer = new IntersectionObserver(
    ([entry]) => {
      // 監視対象が画面内に表示されていない場合（isIntersectingがfalse）、FABを表示
      setShowFab(!entry.isIntersecting);
    },
    { threshold: 0 } // 0%でも表示されていれば「見えている」と判定する
  );

  // 監視対象の要素が存在していれば、observerに登録
  if (searchFormRef.current) {
    observer.observe(searchFormRef.current);
  }

  // コンポーネントがアンマウント（画面から消える）された時、observerを解除（メモリリーク防止）
  return () => observer.disconnect();
}, []);
```



### 4.FABコンポーネントを表示する

最後に、FABを表示するロジックを書きます。

```tsx
<Fab isVisible={showFab} onClick={() => setIsModalOpen(true)} />
```
isVisible は showFab を渡します。


IntersectionObserverを使用することで、フォームの見える・見えないをトリガーにUIを切り替えることができました。

## 参考

https://ja.react.dev/reference/react

https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API
［WSL］作成したファイルが編集できない

WSL上で作成したRubyのファイルをVSCodeで編集しようとすると、エラーが発生したので、解決方法を備忘録として残します。

```
touch chapter4/generate_array.rb
```
で作成したファイルをVSCodeで編集しようとすると、
「十分な権限がありません」と表示されて編集できません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4090811/f1ce9658-8a45-452c-88e0-4c3c7beaa81c.png)

フォルダの権限を確認すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4090811/16ccfc9b-4f69-4809-b34d-b9ed38368eda.png)
chapter4の権限が「root」になっていました。

```
sudo chown -R user:user chapter4
```
これで権限をユーザーに変更し、問題なく保存できるようになりました。


【権限がrootになっていた原因】
```
docker compose run
```
でdockerを起動した後、そのターミナルでRubyファイルを作成していたため。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4090811/15334bf7-d344-4fe8-a84e-3995ab917873.png)
GoのテストコードをGinで初めて書いてみた

# 導入
Goを独学する中で初めて書いた記事です。
ginを使ってみて感じたことを自分なりにまとめます。

# ginとは
GinはGo言語で書かれた軽量で高速なWebフレームワークです。RESTful APIの構築に特化しており、シンプルな記法でルーティングやミドルウェアの設定ができます。今回はGinを使ったWebアプリケーションのテストコードを書いてみました。

# 実際のコード
``` test.go
func TestFind(t *testing.T) {
	// テスト用DBのセットアップ
	db := setupTestDB(t)
	defer db.Close()

	// リポジトリの作成
	repo := NewUserRepository(db)
	ctx := context.Background()

	// テストケース1: 存在するユーザーを検索
	testUser := createTestUser(t, db)
	foundUser, err := repo.Find(ctx, testUser.ID)

	assert.NoError(t, err)
	assert.NotNil(t, foundUser)
	assert.Equal(t, testUser.ID, foundUser.ID)
	assert.Equal(t, testUser.Username, foundUser.Username)
	assert.Equal(t, testUser.Email, foundUser.Email)

	// テストケース2: 存在しないユーザーを検索
	nonExistentUser, err := repo.Find(ctx, 999)

	assert.NoError(t, err)
	assert.Nil(t, nonExistentUser)
}
```

# 躓いたところ
各テストが互いに影響しないよう、テスト実行前後でデータのクリーンアップが必要でした。defer db.Close()でリソースの解放を確実に行うようにしています。
また、testify/assertパッケージの使い方に慣れるまで時間がかかりました。特に、存在しないデータを検索した場合の期待値（assert.Nil）の設定で迷いました。
# まとめ
Goでのテストコード作成を通じて、以下のことを学びました：

1. testingパッケージの基本的な使い方
2. testify/assertを使った効率的なアサーション
3. テスト環境の適切なセットアップとクリーンアップ
4. 正常系・異常系を含む包括的なテストケースの重要性

テストコードを書くことで、コードの品質向上だけでなく、自分のコードに対する理解も深まりました。今後はより複雑なテストシナリオにも挑戦していきたいと思います。
Rails学習メモ（初学者向け）③

# Rails学習メモ（初学者向け）

どうも、nus4です。

Rails講座の学習メモ3回目です。
前回投稿より時間が経ってしまいました…
マイペースではありますが、投稿は継続していきますので、今回もよろしくお願いします！


## 学習方法

- Progate Ruby on Rails5コース
　（Ruby学習に引き続き、愛用させてもらってます！）

## 📝 目次

- [データベースの値を取得する](#データベースの値を取得する)  
- [データベースの中身をビューに表示させる](#データベースの中身をビューに表示させる)  
- [HTMLの入力フォームからデータベースに変更を加える](#htmlの入力フォームからデータベースに変更を加える)  
- [おまけ データベースを降順に並び替える](#おまけ-データベースを降順に並び替える)


## データベースの値を取得する
```bash
# ターミナルコマンド
変数名 = モデル名.find_by(カラム名: 値)
```


## データベースの中身をビューに表示させる
特定のレコードなど、データベースの中身をビューに表示させたい場合、
URLにカラム値を含めてアクション指示を行うと便利です。

コード例
- routesファイル：カラム値を含めたURL名の場合、どのアクションに飛ぶかを追記
- controllerファイル：アクション内でparams変数を使用してURL内の値を取得する
- htmlファイル（表示用ビュー）：アクション内で取得した変数を使用する

```ruby
# routeファイル
get "~~/:URL変数名" => "コントローラ名#アクション名"
#    <---URL--->
```
上記のように、routesファイルを変更することで、":URL変数名"の部分がどの値でも共通のアクションへ飛ばせるようになります。
逆に、どの値でも合致するため、route内では最下行に追加することを意識しましょう。
（routeは上から順に合致するものを探すため）

```ruby
# controllerファイル
def アクション名
    # 変数値を直接取得
    @変数名 = params[:URL変数名]

    # カラム内で変数値に合致するレコードを取得する
    @変数名 = モデル名.find_by(カラム名: params[:URL変数名])
end
```
URL内にある変数値はparamsという変数に[URL変数名: 値]という状態で入っているため、取得は上記の書き方になります。

```erb
<!-- htmlファイル -->
<%= @変数名 %>
```


## HTMLの入力フォームからデータベースに変更を加える
テキストボックスなどの入力値をデータベースに追加する場合は、
*name属性*を使用することで実現できます。

コード例
- htmlファイル(入力用ビュー)：入力フォームに*form_tag*で転送先URLを示し、*name属性名*をつける
- routesファイル：*postアクション*を追加する
- controllerファイル：アクション内でインスタンスを作成し、保存する

```erb
<!-- htmlファイル -->
<%= form_tag("URL") do %>
    # 入力フォーム 例）textarea
    <textarea name="name属性ハッシュ名"></textarea>
<% end %>
```
form_tagとname属性を記入することで、入力値の転送先を正しく指定できます。

```ruby
# routesファイル
post "URL" => "コントローラ名#アクション名"
```
データベースに変更を加える場合は、今までのgetアクションではなく、
*postアクション*にする必要があります。
書き方は基本的にgetアクションと同じです。

```ruby
# controllerファイル
def アクション名
    # name属性値をカラム値とした、データを作成
    @インスタンス名 = モデル名.new(カラム名: params[:name属性ハッシュ名])
    # 作成したデータを保存
    @インスタンス名.save

    # postアクションで対応するビュー(URL)に転送する
    redirect_to("/URL")
end
```
アクション内ではredirect_toを使用することでも、他のURLに転送（リダイレクト）を行うことが可能です。


## おまけ データベースを降順に並び替える
orderメソッドでデータベースを並び替えてから表示させることが可能です。
":desc"だと降順で、":asc"だと昇順に並び替わります。

```ruby
# controllerファイル
def アクション名
    @変数名 = モデル名.all.order(カラム名: :desc)
end
```
*変数は配列型になります*

いかがでしたでしょうか。
まとめるのに苦戦していまして、改善があれば今後も適宜更新する予定です！
SQLServerへの接続がSSL無効にしたのになぜか接続ができない場合確認する場所

## SQL ServerでSSL接続エラー時に確認すべきログの場所

SQL Serverで「クライアントはSSL無効で接続しようとしているのに、サーバー側でSSL有効が強制されて接続できない」などSSL/TLS関連のエラーが発生した場合、以下のログや場所を確認する。

### SQL Serverエラーログ（ERRORLOG)

* サーバー上で読み込まれた証明書や暗号化関連の情報は、SQL Serverのエラーログ（通常はERRORLOGファイル）に記録される。
* 証明書のロード状況や自己署名証明書の利用有無、証明書のハッシュ値などもここで確認できる。
* ログディレクトリは、SQL Serverインスタンスのデフォルト設定やSQL Server Configuration Managerで確認できます。

```
C:\Program Files\Microsoft SQL Server\MSSQL.<インスタンス番号>\MSSQL\LOG\ERRORLOG

もしくは

C:\Program Files\Microsoft SQL Server\MSSQL<バージョン>.<インスタンス名>\MSSQL\Log
```

* 実際の保存場所は、SQL Server構成マネージャーの「SQL Serverのサービス」→対象インスタンスの「プロパティ」→「起動時のパラメーター」タブで「-e」パラメータとして確認できる。


### Windowsイベントログ（システムイベントログ）

* SSL/TLSハンドシェイクの失敗や証明書の信頼性問題は、Windowsの「システム」イベントログにも記録される。
* 特に「Schannel」ソースのエラー（例：Event ID 36882）は証明書の信頼性やTLS通信エラーの詳細を示す。


* 信頼されていない証明書による失敗（Event ID: `36882`）の例

```
Log Name: System
Source: Schannel
Date: <日時>
Event ID: 36882
Task Category: None
Level: Error
User: <ユーザー名>
Computer: <コンピュータ名>
Description:
The certificate received from the remote server was issued by an untrusted certificate authority. Because of this, none of the data contained in the certificate can be validated. The TLS connection request has failed. The attached data contains the server certificate.
```

* 致命的なTLSエラー（Event ID: `36888`）

```
Log Name: System
Source: Schannel
Date: <日時>
Event ID: 36888
Task Category: None
Level: Error
User: <ユーザー名>
Computer: <コンピュータ名>
Description:
A fatal alert was generated and sent to the remote endpoint. This may result in termination of the connection. The TLS protocol defined fatal error code is <コード>. The Windows SChannel error state is <状態>.
```



### SQL Server構成マネージャの設定確認

* 「SQL Server Network Configuration」→「Protocols for 」→「プロパティ」→「Flags」タブで「Force Encryption」の値を確認。
* 「Certificate」タブでどの証明書が使用されているか確認できる。
* 「Force Encryption」（暗号化の強制）オプションの初期値は「いいえ（No）」。



### レジストリ設定（TLS/SSLプロトコルの有効・無効）

* TLS/SSLの有効・無効設定は、Windowsレジストリの以下のキーで確認できます。

```
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
```

* クライアント・サーバー両方のTLSバージョン有効状態を確認

## まとめ

- SQL Serverのエラーログ（ERRORLOG）
- Windowsシステムイベントログ（Schannelエラー）
- SQL Server構成マネージャの暗号化・証明書設定
- WindowsレジストリのTLS/SSLプロトコル設定

これらを順に確認し、証明書の状態や暗号化強制設定、TLSバージョンの整合性をチェックする


## Glue v5でSQLServerへの接続ができなくなった場合

* AWS Glue v4では、SQL ServerへのJDBC接続時にSSL（暗号化）を無効化しても接続できていましたが、Glue v5ではSSL無効だと接続できなくなった理由は、JDBCドライバーやGlueランタイムのセキュリティポリシーが強化されたため。
* JDBC URLで`encrypt=false`や類似のパラメータを指定しても、接続が拒否されるケースが増えているらしい。
* 証明書検証スキップ（非推奨）するには以下

```
encrypt=true;trustServerCertificate=true	
```

* https://docs.aws.amazon.com/ja_jp/glue/latest/dg/migrating-version-50.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/e8fe93b7-c8fc-4ce3-b990-298dc0ed248b.png)
Google Scholarで被引用数順に論文を表示

自分用まとめ

目次
- [手順](#手順)
- [オプション](#オプション)

# 手順
参考
https://github.com/WittmannF/sort-google-scholar

1.　最新バージョン`sortgs`とその依存関係をインストール
```
pip install sortgs
```
2.　キーワードに関連する上位100件の検索結果を`検索したいキーワード.csv`として現在のディレクトリに作成する
```
sortgs "検索したいキーワード"
```
	
# オプション
年ごとの被引用数で並び替え：
`--sortby "cit/year"`


年範囲を指定：
`--startyear XXXX --endyear XXXX`


正確なキーワードを検索：
`sortgs "'検索したいキーワード'"`


結果を特定のパスに保存：
`--csvpath '任意のパス'`


複数のキーワード検索：
`sortgs '"検索したいキーワード1" OR "検索したいキーワード2"'`


言語フィルター：
e.g.
`--langfilter pt es fr de`
：ポルトガル語、スペイン語、フランス語、ドイツ語の記事のみが含まれる

用意されている言語：zh-CN, zh-TW, nl, en, fr, de, it, ja, ko, pl, pt, es, tr


件数の指定：
`--nresults 件数`

デフォルトでは100になっている：Google ScholarはCAPTCHAチェックのため、リクエストが多すぎるとアクセスをブロックする場合があることから、件数が多いときには注意が必要


CSVファイルに保存しない：
`--notsavecsv`


出力例：
実行中は`sortgs`ターミナルに更新が表示される：
```
❯ sortgs "'machine learning'"
Running with the following parameters:
Keyword: 'machine learning', Number of results: 100, Save database: True, Path: /Users/wittmann/sort-google-scholar, Sort by: Citations, Plot results: False, Start year: None, End year: 2023, Debug: False
Loading next 10 results
Loading next 20 results
...
```
Oracle11gへの接続が特定のアカウントだとなぜか接続ができない場合、リスナーログ（listener.log）を確認する

## 以下のケースでは関係ない

* Oracle 11gでは、アカウントごとに特定のIPアドレスからの接続のみを許可・拒否する機能は、データベース自体の標準機能としては備わっていない。
* リスナー設定 listener.oraで「どのIPアドレスやポートで接続を受け付けるか」は指定できるが、アカウント単位ではなく、サーバー全体やリスナー単位の制御。
* OSやネットワークレベルのファイアウォールで、特定IPアドレスからの接続のみを許可することはあるが、アカウント単位ではなく、サーバーやポート単位の制御。
* アプリケーションがDB接続時に、IPアドレスやユーザー名をチェックして制御することは可能だが、DB直接の接続の場合はアプリケーションは経由しないので関係ない。


## まずはログファイルを確認


### リスナーログ（listener.log）

* クライアントからの接続要求や接続エラー（TNS-エラーなど）が記録される。

```sh
$ORACLE_BASE/diag/tnslsnr/<ホスト名>/<リスナー名>/trace/listener.log
```

以下は失敗のログの例

> 19-NOV-2020 02:10:01 * (CONNECT_DATA=(SERVICE_NAME=hogepdb)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.104)(PORT=64500)) * establish * hogepdb * 12514
TNS-12514: TNS:listener does not currently know of service requested in connect descriptor



以下は成功例（最後に 0 がある。）

> 19-NOV-2020 02:08:33 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=hogepdb)(CID=(PROGRAM=sqlplus@ol77)(HOST=ol77)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.103)(PORT=64384)) * establish * hogepdb * 0



### アラートログ（alert log）認証エラー時

* データベースの重大なイベントやエラー（ORA-01017エラーなど）が記録される

```sh
$ORACLE_BASE/diag/rdbms/<DB名>/<インスタンス名>/trace/alert_<インスタンス名>.log
```

## ログイントリガで接続をはじく方法もありはする 

* PL/SQLのAFTER LOGONトリガとV$SESSIONなどを使い、接続時にIPアドレスやユーザー名をチェックし、条件に合わなければRAISE_APPLICATION_ERRORで切断する方法がある。
* ただし、これは公式サポート外の運用。

```sql
CREATE OR REPLACE TRIGGER valid_ip
AFTER LOGON ON DATABASE
DECLARE
    v_ip   VARCHAR2(30);
BEGIN
    -- V$SESSIONから現在のセッションのIPアドレスを取得
    SELECT SYS_CONTEXT('USERENV', 'IP_ADDRESS') INTO v_ip FROM DUAL;

    -- ユーザーごとにIPアドレスチェック
    IF (USER = 'TARGET_USER' AND v_ip NOT IN ('192.168.1.100', '127.0.0.1')) THEN
        RAISE_APPLICATION_ERROR(-20001, 'このIPアドレスからの接続は許可されていません');
    END IF;
END;
/
```

### 設定の確認

```sql
SELECT OWNER, TRIGGER_NAME, STATUS, DESCRIPTION
FROM ALL_TRIGGERS
WHERE TRIGGER_TYPE = 'AFTER LOGON ON DATABASE';
```

```sql
SELECT TRIGGER_NAME, STATUS, DESCRIPTION
FROM USER_TRIGGERS
WHERE TRIGGER_TYPE = 'AFTER LOGON ON SCHEMA';
```
【CI3】dbutil() で「DB driver がありません」と言われた時の対処法（PHP 8.1対応）

# CodeIgniter 3.1.13 + PHP 8.1 で dbutil() が「DB driver がない」と怒られた話

CodeIgniter 3.1.13 を PHP 8.1 の環境で使っていて、  
`dbutil()` を呼び出すと **「DB ドライバがない」系のエラーが出ることがありました。

---

## 🐛 発生した問題

Model で `$this->load->database()` しているのに、以下のようなエラーが出ました
原因は `dbutil()` を呼び出すときに、**明示的に `$this->db` を渡していなかったこと**でした。

---

## 💡 原因の考察

CodeIgniter の `dbutil` ライブラリは、`$this->load->dbutil()` で読み込めますが、  
PHP 8.1 では変数の null チェックや型の厳格さが増しているため、  
内部的に `$this->db` がうまく渡っていないと、正しく初期化できないようです。

---

## ✅ 解決方法
```
$this->load->dbutil($this->db);
```
このように 明示的に $this->db を渡すことで、DB ドライバを正しく認識させることができます！

## 📝 まとめ

- CodeIgniter 3.1.13 を PHP 8.1 で使うと、`dbutil()` がエラーになることがある
- 原因は `$this->load->dbutil();` のように **明示的に DB 接続を渡していないこと**
- 解決方法は `$this->load->dbutil($this->db);` と **DB 接続を明示的に渡すこと**
- エラーメッセージは「DB driver がない」「Invalid argument supplied for foreach()」など

---

Qiita 初投稿なので、誤りや改善点があればコメントで教えてください🙏  
誰かの助けになれば嬉しいです😊
SQLServerで読み取り専用アカウントを作成、参照できるテーブルを制限、CPU使用率を制限したい場合

## 読み取り専用アカウントを作成するには

### SQLコマンドの場合

```sql
CREATE LOGIN read_only_user WITH PASSWORD = 'password!';
```

```sql
USE 対象データベース名;

CREATE USER read_only_user FOR LOGIN read_only_user;

-- db_datareaderロールのみ付与でSELECT権限を与える
ALTER ROLE db_datareader ADD MEMBER read_only_user;

-- db_denydatawriter も付与することで、誤ってINSERT/UPDATE/DELETE権限が付与されるのを防げる
ALTER ROLE db_denydatawriter ADD MEMBER read_only_user;
```


### GUIからの場合

```:アカウントの作成
SSMSでサーバーに接続

「セキュリティ」→「ログイン」右クリック→「新しいログイン」

ログイン名、認証方式（SQL Server認証 or Windows認証）、パスワードを設定
```

```:アカウントに権限設定
「ログイン」作成後、「ユーザーマッピング」タブで対象データベースを選択

「データベース ロールメンバシップ」で

「db_datareader」（読み取り専用）

「db_denydatawriter」（書き込み禁止）
をチェックしてOK
```

* SSMS (SQL Server Management Studio) は GUI管理ツール
* コマンドラインだと sqlcmd


## 読み取り専用アカウントでかつ参照できるカラムを制限したい

```sql
CREATE LOGIN read_only_user WITH PASSWORD = 'password!';

USE 対象データベース名;
CREATE USER read_only_user FOR LOGIN read_only_user;

GRANT SELECT ON dbo.テーブル名1 TO read_only_user;
GRANT SELECT ON dbo.テーブル名2 TO read_only_user;
-- 必要なテーブル分繰り返す
```

不要な権限の付与を避ける。
db_datareaderロールを付与すると「全テーブル参照可能」になるため、付与しない。
INSERT/UPDATE/DELETEなどの権限は何も付与しなければ、デフォルトで持たない。
（必要に応じて）他のオブジェクトの権限も調整
ビューやストアドプロシージャ等も必要に応じて個別にGRANTする。



## CPU使用率の制限 （Enterprise Editionで利用可能）

```sql
-- CPU10%までのリソースプール作成
CREATE RESOURCE POOL ReadOnlyPool WITH (MAX_CPU_PERCENT = 10);

-- グループ作成
CREATE WORKLOAD GROUP ReadOnlyGroup USING ReadOnlyPool;

-- ログイン名で所属グループ判定
CREATE FUNCTION dbo.MyClassifier()
RETURNS sysname
WITH SCHEMABINDING
AS
BEGIN
    IF ORIGINAL_LOGIN() = N'read_only_user'
        RETURN N'ReadOnlyGroup';
    RETURN N'default';
END;

-- Resource Governorに分類子関数を設定
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = dbo.MyClassifier);
ALTER RESOURCE GOVERNOR RECONFIGURE;
```

* リソース ガバナーは、SQL Serverでユーザーやアプリケーションごとのクエリが使用できるCPU、メモリ、物理I/Oなどのリソース量を「予約」または「制限」できる機能。
* SQL Server Enterprise Editionで利用可能 （SQL Server Standard Editionでは利用できない。）
Unity 産業DXカンファレンス 2025 - 東京 参加メモ


# Unity 産業DXカンファレンス 2025 - 東京

イベント全体の雰囲気として、具体的な事例も交えた地に足のついた話が多かった。
<img width="600" alt="all.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906735/78b5cedc-0b28-42b7-91bb-854d9b778681.jpeg">
ホールA・Bがあり、Aでは展示とBでの講演映像が見られる。

# 講演

### 1. トヨタ・レクサスの次世代HMI開発とUnity

-   **テーマ**： SDV (ソフトウェアで定義される車) のHMI (メーター/ナビ)
-   **技術スタック**:
    -   UI： `Flutter`
    -   3D表示： `Unity` 
    -   特注マイコン上に実装
-   「Unity Asset Manager」を活用
    > デザイナーとの協業を円滑化するアセット・3Dモデル管理ツール。
    > - アセット毎のチャット機能
    > - カラバリ等のバリエーション管理も可能

### 2. 明電：XR技術を活用した教育事例の紹介

-   **テーマ**： 安全教育と技術伝承
-   **事例**:
    -   **労災体験VR**： 労災シーンを数十種類用意。**振動・傾斜する床と連携**し、没入感と危険体感度を向上。１万人ほどの利用者。
    -   **製品講義VR**： 巨大/開発中/内部構造など、リアルでは見せにくいモノに最適。オンラインVR上で講師と受講者が3Dモデルを囲んで講義。
-   制作のポイント
    - シンプル： 情報を詰め込みすぎない。複雑な操作系ではなく、触れるだけでOK等。
    - 動画でできないことを意識： 断面表示やインタラクションなど、3Dならではの体験を
    - 視線誘導： ユーザーに見せたい場所へ自然に注目させる工夫。音声を活用したり、パーツを赤く光らせる等。

# 展示ブース


## デバイス
### パナソニック：meganeX
<img width="500" alt="panasonic.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906735/a4d40d4f-de40-4021-b76c-ba13622df9fc.jpeg">x
- 画質：QUESTに比べ、画質と黒色の再現が良い。片目4K画質
- 重量・フィット感：QUESTに比べ軽い。目元を圧迫しないため装着感が少ない（特に目元下部）。後頭部へのフィット部は試作段階品で今後販売予定とのこと。
- 広範囲に度数調整対応できるレンズが入っているため裸眼で可能。


### キャノン：MREAL
- 現実とCGの奥行を考慮した描画が特徴。ただ、手の一部が奥判定となり、消えていたので今後の精度向上に期待。
### ソニー：空間再現ディスプレイ
- 裸眼で立体っぽく見せる。立体物があると勘違いするほどではなかったため、今後の精度向上に期待。
<img width="600" alt="sony.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906735/bef697cc-bd39-4a36-bab7-67272047195f.jpeg">


### イノラックスジャパン：煌めきディスプレイ
- ホログラムのような感じで、見る位置に応じて光の反射が変わって光沢があるように見える。
- コインの反射に統一感がないため今後に期待。
     ![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906735/bacd6690-f008-451d-a636-5f20189a1c45.gif)

## デモ
### 積木製作：VRトレーニング

<img width="600" alt="tumiki.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906735/2eecbd7b-42db-49b1-9a4b-8b799be90ed3.jpeg">

#### ANAの訓練シミュレーター
- HMDとハンドルデバイスを組み合わせており、没入感が高い
- ハンドトラッキングで指差し確認の判定も可能
- 最後には評価システムがあり、改善すべき項目が分かる
- ６シチュエーションほどで、製作期間は１年半とのこと

<img width="600" alt="meiden.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906735/7e2eaf87-483a-4e20-908f-1052a723db22.jpeg">

#### ドローン資格取得のためのトレーニング
- ２種免許をとれるようになるトレーニングシステム
- VR空間上でドローンを操作するため、ドローンを壊す心配がない
- ドローンの慣性が効いており、リアルに近い

### 明電：安全体験教育

<img width="500" alt="meiden.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906735/2a1a2cf6-d34d-48e4-83d2-ee6999cc81b4.jpeg">

- 数十種類の労災シーンから、階段から滑り落ちるシーンを選択
- 転倒時には地面が激しく振動し、没入感が高い
- 労災発生時のシーンだけではなく前後のシナリオも組み込まれていた
    - 急ぎの呼び出しの電話
    - 階段から落ちて指を失う
    - 最後に反省点の振り返り

### ホロラボ
#### クラウド上での点群表示
- クラウド上なのでタブレットでも快適に動作
#### モーション記録
- HMDのハンドトラッキングによって職人の手さばきを記録することができるようになった
- 3D空間に以下を配置し技術の伝承を図る　
    - 商品の3Dモデル
    - 記録した手さばき
    - 説明の文章・動画
- 商品の3Dモデルは、Scaniverseで作成しており、現状モーションといったフィードバックなし。
- エクセルに記録した説明内容・動画・3Dモデルなどを読み取って、3D空間を生成。

### EARTHBRAIN
- ドローンによって、工事現場の3Dモデルや点群データを作成
    - 地面高低差の変化を見て、進捗を確認
- コマツ重機に設置されたカメラでリアルタイムに状況を確認できる
- 重機の遠隔コントロールも可

# 所感
展示では、様々なデバイスをもちいた体験デモが多かったので良かった。
安全教育やトレーニングデモでは、ゲーム的な要素が盛り込まれており良かった。
VR・XRブームが落ち着いた現時点だからこそ、真の価値を提供している企業が見受けられた。
AWS Bedrock と Knowledge Bases を使用して RAG を実現してみた

# はじめに

こんにちは.

AWS Bedrock + Knowledge Bases + S3 + OpenSearch を使用して RAG を実現します.

aws-cdk の Bedrock L2 Construct 対応は進んできています.

https://github.com/aws/aws-cdk/pull/34065

しかしながら, なるべくサクッと実現するために今回ご紹介するコードでは

https://github.com/awslabs/generative-ai-cdk-constructs

を使用してみました.


# 構成

```
User ---> Bedrock Agent ---> Knowledge Bases ---> OpenSearch(Serverless)
                                   └── S3
```

# AWS リソースの作成・設定

https://github.com/dev-kawano-y/study-aws-bedrock-agent-with-knowledge-bases

```
$ git clone https://github.com/dev-kawano-y/study-aws-bedrock-agent-with-knowledge-bases.git
$ cd study-aws-bedrock-agent-with-knowledge-bases
$ npm ci
```

```bash:AWS リソースの作成
$ cd infrastructures
$ npx cdk deploy InfrastructuresStack --profile ...
```

- リソースが作成されたら AWS Management Console から Knowledge Bases とデータを同期してください
![スクリーンショット 2025-06-12 16.12.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929098/5c4a914f-9c33-49ed-8440-1a0d58afdcdf.png)
  - Amazon Bedrock コンソール > ナレッジベース > [ナレッジベースを選択] > データソース > 同期
  https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/kb-data-source-sync-ingest.html

# 動作確認

Amazon Bedrock コンソール > エージェント > [エージェントを選択] > テスト

## RAG 用のドキュメントあり

![スクリーンショット 2025-06-12 16.14.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929098/3feed692-0eaf-42d9-be57-9ababc51a6ea.png)

RAG 用のドキュメントは [こちら](https://github.com/dev-kawano-y/study-aws-bedrock-agent-with-knowledge-bases/tree/main/infrastructures/rag/docs)
応答を見ると問題なさそうですね.

## おまけ: RAG 用のドキュメントなし

![スクリーンショット 2025-06-12 16.04.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929098/80ab2b7a-36f2-4cc6-a8dd-5999f02b8ae1.png)

RAG 用のドキュメントを設定しないと期待する応答を得ることができませんでした.


# AWS リソースの削除

```bash:AWS リソースの削除

$ npx cdk destroy InfrastructuresStack --profile ...
```

# 最後に

OpenSearch はまあまあ良いお値段するので, お試し後は削除をお忘れなく.
Azure OpenAI リソースを初作成時のエラー対処法

# Azure OpenAI リソース作成時に表示される「リソースプロバイダー未登録」エラーの対処法

## 🛑 発生するエラーと原因
サブスクリプションに初利用Azure OpenAIリソースを作成すると、以下メッセージは提示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1348505/152f86db-4cae-4d79-9596-3176ea413f97.png)

そのメッセージをクリックすると、以下リンクに飛ばされ、リソースプロバイダーを登録してねとのことが分かります。
https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/error-register-resource-provider?tabs=azure-portal&WT.mc_id=Portal-Microsoft_Azure_ProjectOxford


これは、`Microsoft.CognitiveServices` リソースプロバイダーが未登録の状態であるために発生します。

## 🔧 解消方法
### ステップ1：リソースプロバイダーの状態確認
1. Azure Portal で「サブスクリプション」へ移動
2. 「設定」＞「リソースプロバイダー」を選択
3. `Microsoft.CognitiveServices` を検索
4. ステータスが「未登録」や「登録解除」になっている場合、「登録」または「再登録」をクリック


サブスクリプションには以下の状態になる必要があります。
（サブスクリプションー＞設定ー＞リソースプロバイダー）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1348505/7a7a4cbd-a08d-49b6-a3f8-bbb9eee0bc2f.png)

### ステップ2：リトライ
その後、再度 OpenAI リソース作成を実行すると正常に完了することがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1348505/1fdf48d7-d6de-43ca-a3cd-547775e823b9.png)

また、場合によって、該当状況でも利用できない可能性があります。
➞　再登録でやったら解消されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1348505/e36946a6-c433-45a4-8eab-391c6a470d76.png)



## ❗ 注意点

- Azure OpenAI Service は申請制で、全てのサブスクリプションで利用できるわけではありません。
- 申請状況や制限事項は以下のドキュメントを確認してください。

🔗 [Azure OpenAI Service の使用制限（Microsoft公式）](https://learn.microsoft.com/en-us/legal/cognitive-services/openai/limited-access)

- デフォルト有効かどうかのリソースプロバイダー一覧
https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-services-resource-providers#find-resource-provider
データベーススペシャリスト合格までの勉強方法

## はじめに

令和６年度秋期 データベーススペシャリスト試験に合格したため、勉強方法の記録を残します。  
今後受験する方の参考になれば幸いです。

## 結果

| 試験区分     | 得点・結果 |
|-------------|-----------|
| 午前Ⅰ得点   | 免除      |
| 午前Ⅱ得点   | 76.00点   |
| 午後Ⅰ得点   | 81点      |
| 午後Ⅱ得点   | 60点      |
| 最終結果     | 合格      |

## 勉強方法

勉強時間の合計は約74.5時間。  
平日は0.5～1時間、休日は2時間程度で、2.5ヶ月にわたって取り組みました。

### 午前Ⅰ

**勉強時間：無し**
2年以内で応用情報技術者試験に合格していたため、免除。  
もし勉強するなら過去問道場を使用したと思います。

### 午前Ⅱ

- **勉強時間：22.5時間**  
  ┣ 教科書：15時間  
  ┗ 過去問道場：7.5時間  
- 勉強方法：
  - **教科書を一周する。**  
    [徹底攻略 データベーススペシャリスト教科書](https://x.gd/xPTOu)を使用しました。  
    ひとまず一周してなんとなく全体像をつかみ、その後は辞書として使いました。
    ※後述しますが、午後の過去問の解説が収録されており、これに大変助けられました。
  - **過去問道場を隙間時間に解き続ける。**  
    解説をその場で確認したかったので、有料メンバーシップに登録をしていました。  
    隙間時間にポチポチやるのであれば、メンバーシップ登録は非常に有効でした。

### 午後Ⅰ、午後Ⅱ

- **勉強時間：52時間**  
- 勉強方法：  
  **どちらも過去3年分を2周、過去5年分を1周する。（計8周）**  
  教科書に過去問の解説がついているので、理解できるまで読み込みました。
  - 午後Ⅰ  
    選択と言えど、数が少ないので全て解きました。
  - 午後Ⅱ  
    3年分の2周はすべて解きましたが、残りは片方に絞って解きました。  
    午後Ⅰを通してリレーションシップ図の完成は避けられないため、重点的に勉強していました。

## 選択科目

### 午後Ⅰ

- **問1と問2を選択。**  
  ざっと問題を見て、解きやすそうな2問を選択しました。  
  計算問題に苦手意識があったため、問3は避けました。

### 午後Ⅱ

- **問2を選択。**  
  リレーションシップ図の完成と、属性名の補完のみの問題でした。  
  過去問で類似問題を繰り返し解いていたため、こちらを選択しました。

## 所感

正規化や分離レベルについて、改めて体系的に学び直す良い機会となりました。  
試験対策としては、「徹底攻略 データベーススペシャリスト教科書」を過去問含めてしっかりやりこめば十分合格できると感じました。

午後Ⅱがギリギリ過ぎましたが、回答欄を全て埋めたのが吉と出たかなと感じます。  
受かったからよかったものの、全体的にやや勉強時間が足りていなかったと反省しています。  

受験からずいぶん時間が経ってしまいましたが、書きかけのファイルを見つけたため、せっかくなので公開します。
Oracle 11gでシノニム（恒久的な別名）をつけたい場合

シノニム（synonym）という言葉は、ギリシャ語が語源。
「同じ」を意味する「syn」と、「名前」を意味する「onyma（またはonoma）」の2つの語が組み合わさった。



## シノニムの作成・削除

```sql
-- シノニムを作成する場合
CREATE SYNONYM my_emp FOR scott.emp;

-- select
SELECT * FROM my_emp;

-- シノニムを削除する場合
DROP SYNONYM my_emp;
```

```sql:publicシノニム
-- シノニムを作成する場合
CREATE PUBLIC SYNONYM emp FOR hr.employees; 

SELECT * FROM emp;

-- シノニムを削除する場合
DROP PUBLIC SYNONYM emp;
```

## シノニム一覧を表示

### ユーザーが作成したシノニム一覧

```sql
SELECT SYNONYM_NAME, TABLE_OWNER, TABLE_NAME
FROM USER_SYNONYMS;
```

### 自分が参照できるすべてのシノニムを表示 (ALL_SYNONYMS)

```sql
SELECT OWNER, SYNONYM_NAME, TABLE_OWNER, TABLE_NAME
FROM ALL_SYNONYMS;
```

### データベース内の全シノニム（DBA権限が必要）

```sql
SELECT OWNER, SYNONYM_NAME, TABLE_OWNER, TABLE_NAME
FROM DBA_SYNONYMS;
```

### publicシノニムのみ

* publicシノニムは、全ユーザーが共通してアクセスできる別名

```sql
SELECT SYNONYM_NAME, TABLE_OWNER, TABLE_NAME
FROM DBA_SYNONYMS
WHERE OWNER = 'PUBLIC';
```
aliasの設定方法

自分用まとめ

# 目次
- [使用シェルの確認方法](#使用シェルの確認方法)
- [profileとrcの違い](#profileとrcの違い)
- [aliasの設定手順](#aliasの設定手順)
- [参考文献](#参考文献)

# 使用シェルの確認方法
```
$ echo $SHELL
```
と打って
```
/bin/bash
```
と出てきたらBashを、
```
/bin/zsh
```
と出てきたらZshを使っている。
- macOS Catalina以降 → デフォルトで zsh
- Linuxなど多くのディストリビューション → デフォルトで bash

# profileとrcの違い
profile
ログインシェルの起動時※1に一度だけ読み込まれる
※1 ターミナルを起動したときや、SSHでリモート接続したとき

rc
ログインシェル※2およびインタラクティブシェルの起動時※3に毎回読み込まれる
※2 profileの中にrcを読み込むように書いてあると、profile読み込みのタイミングに読み込まれる
※3 コマンドでbashやzshを起動して手動でシェルを起動したとき

# aliasの設定手順
1.　ホームディレクトリ直下のrcファイルをエディタで開く
```
vi ~/.zshrc
```

2.　aliasを記述し、保存して終了
```
alias [ショートカットコマンド名]="本来のコマンド名"
```

3.　rcファイルを読み込む
```
source ~/.zshrc
```

# 参考文献
1. [[bash, zsh] profileとrcの使い分け問題で、なぜ「とりあえず全部profileでok」と思われがちか。そもそも「全部profile」は本当にダメなのか](https://qiita.com/OritaK/items/28392bd6d24f1183dbd5)
2. [開発者であれば最初はきっと沼る、PATHと.zshrc周りを調べまくったので備忘録](https://qiita.com/ishidao/items/769b2e9acfc2ce4542b6)
Oracle 11gで読み取り専用アカウントを作成し参照できるテーブルを制限したい場合

## ユーザー作成

```sql
-- ユーザー作成
CREATE USER readonly_user IDENTIFIED BY "password";

-- 接続権限付与
GRANT CREATE SESSION TO readonly_user;
```

## readonly_userに対して参照できるテーブルを制限する

特定のテーブルだけSELECT権限を付与し、それ以外の権限を与えなければ、そのユーザーは指定したテーブルのみ参照可能です。

```sql
-- SCOTTスキーマのEMPとDEPTテーブルだけ参照させる場合
GRANT SELECT ON scott.emp TO readonly_user;
GRANT SELECT ON scott.dept TO readonly_user;
```

## 上記コマンドを取り消しするには

```sql
REVOKE SELECT ON scott.emp FROM readonly_user;
REVOKE SELECT ON scott.dept FROM readonly_user;

REVOKE CREATE SESSION FROM readonly_user;
DROP USER readonly_user;
```


## ビューを作成してテーブルのカラムを制限するには

### 設定

```sql
-- 必要なカラムだけを含むビューを作成
CREATE VIEW schema1.v_table1 AS
SELECT col1, col2 FROM schema1.table1;

-- ビューにだけSELECT権限を付与
GRANT SELECT ON schema1.v_table1 TO readonly_user;
```


### 設定削除

```sql
DROP VIEW schema1.v_table1;
```

```sql
REVOKE SELECT ON schema1.v_table1 FROM readonly_user;
```

---

## 冗長化について

* Oracle 11gの冗長化構成で最も一般的な例は、`Oracle Data Guard`を利用したプライマリ（本番）データベースとスタンバイ（待機）データベースの構成です。
* Data Guardでは、プライマリDBで発生したトランザクションログ（REDOログ）をネットワーク経由でスタンバイDBに送信・適用し、リアルタイムまたは遅延で同期します。障害発生時には、スタンバイDBを昇格させて業務継続が可能です。

### 読み取り専用のクエリ発行が可能

* Oracle 11g Data Guardのフィジカル・スタンバイ・データベースでは、特定のモードでSELECT（読取り専用クエリ）が可能。

### 冗長化の確認

```
SELECT DATABASE_ROLE, PROTECTION_MODE FROM V$DATABASE;
```

DATABASE_ROLEが
PRIMARYまたは
PHYSICAL STANDBY/LOGICAL STANDBY ならData Guard構成。

* 現在接続中のセッションや接続元IPアドレスは、V$SESSIONビューから確認できます。

```:sql
SELECT MACHINE, PROGRAM, STATUS FROM V$SESSION;
```
【Android】Java エラーリスト - 更新型マイノート

![ErrorList.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936031/656262cf-c85c-4709-9c5c-85393faf03d5.png)

## android.content.ActivityNotFoundException:
 **【エラーログ】**
```:Logcat
android.content.ActivityNotFoundException:
Unable to find explicit activity class
{sample/sample.ui.registerdevice.RegisterDeviceActivity};
have you declared this activity in your AndroidManifest.xml, 
or does your intent not match its declared <intent-filter>?
```
**【解消手順】**

**AndroidManifest.xmlに以下の記述を追加する**
```xml:AndroidManifest.xml
<activity
    android:name=".ui.sample.SampleActivity"
    android:exported="false" />
```
手動でActivityのクラスファイルを追加時、AndroidManifest.xmlに自動追加されないので注意
AndroidManifestにある場合は、パッケージ名などを確認する。

https://b0npu.hatenablog.com/entry/2016/09/18/182623
Oracle 11gでアカウントごとのCPU上限を設定

## Oracle 11gでリソース・マネージャによるCPUやメモリなどのリソース制御を行う

Oracle 11gでは「リソース・マネージャ」を利用して、ユーザーやグループごとにCPUやその他リソースの割り当て上限を細かく制御できる。

```sql:設定
BEGIN

  -- SUBMIT_PENDING_AREA()するまで反映しない
  DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();

  -- リソース・プランの作成
  DBMS_RESOURCE_MANAGER.CREATE_PLAN(
    PLAN    => 'CPU_PLAN',
    COMMENT => 'CPU使用率制限用プラン'
  );
  
  -- コンシューマ・グループの作成（必要に応じて）
  DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP(
    CONSUMER_GROUP => 'LIMITED_USERS',
    COMMENT        => '制限対象ユーザーグループ'
  );
  
  -- プラン・ディレクティブの設定
  -- 例：LIMITED_USERSグループにCPU使用率20%の上限を設定
  DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
    PLAN             => 'CPU_PLAN',
    GROUP_OR_SUBPLAN => 'LIMITED_USERS',
    COMMENT          => '制限ユーザー用',
    UTILIZATION_LIMIT => 20
  );

  -- 設定の確定
  DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA();
  DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();

END;
```

---

### 制限を適用したいユーザーをコンシューマ・グループに割り当て

```sql
EXEC DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP('対象ユーザー', 'LIMITED_USERS', TRUE);
ALTER USER 対象ユーザー DEFAULT CONSUMER GROUP LIMITED_USERS;
```

### リソース・プランの有効化

```sql
ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = 'CPU_PLAN';
```

これで設定したリソース・プランが有効になり、指定したグループごとにCPUなどのリソース上限が適用される。

## 確認

設定内容や有効化状況は、`DBA_RSRC_PLAN_DIRECTIVES`や`V$RSRC_PLAN`で確認。

```sql
-- 現在有効なリソースプラン
SELECT name, is_top_plan FROM v$rsrc_plan;

-- プランのディレクティブ内容
SELECT PLAN, GROUP_OR_SUBPLAN, TYPE, MGMT_P1, UTILIZATION_LIMIT
FROM DBA_RSRC_PLAN_DIRECTIVES
WHERE PLAN = 'CPU_PLAN';
```

## mysqlでは

* MySQL 5.x/8.0の標準ユーザー制限機能では、CPU上限は直接設定できない。
    * 1時間当たりのクエリなどの上限設定、
    * 同時接続数の設定は可能。
* 8.0から仮想CPU単位でスレッドをグループに割り当てることで、CPUリソースの制御が可能になった。


```sql
CREATE USER 'username'@'host'
  IDENTIFIED BY 'password'
  WITH
    MAX_QUERIES_PER_HOUR 1000
    MAX_UPDATES_PER_HOUR 500
    MAX_CONNECTIONS_PER_HOUR 100
    MAX_USER_CONNECTIONS 5;
```

* PostgreSQLでも同様にOracleのようには設定できない。(OS側のcgroup設定などで工夫する)

## mariadbでは

* ColumnStoreエンジンでUserPriorityを使うことでできる。
    * MariaDB ColumnStoreは、通常のMariaDBとは異なり「カラム型」「分散並列処理」「分析特化」のエンジン。
* 標準のMariaDBサーバー（InnoDB/MyISAMなど）では利用できない。

テーブル作成時にENGINE=ColumnStoreを指定することでカラム型テーブルを作成できる。

* https://mariadb.com/kb/ja/columnstore-database-user-management/
Data Factory パイプラインで、スキップされる可能性のあるアクティビティの output を安全に取得する

## はじめに

アクティビティの出力は以下のように取得できます。

```

activity('<アクティビティ名>').output.<プロパティ>

```

たとえば、以下のパイプラインにて

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f2936d38-28f8-4a67-9f5f-d8c4b2d2c3c6.png)

このように記述すると、変数に読取データ量がセットされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/d85faeb1-c147-4dfe-a5f5-3387fb6c65dd.png)

結果：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/40f153c2-576a-46a5-bfb9-a744b28de34e.png)

このような実装において、対象のアクティビティがスキップされるなど実行されなかったアクティビティを参照している場合、参照エラーとなってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8d17fe54-b0d4-4062-875a-30f98d9288d9.png)

この記事ではこのような実装における対処を共有します。


## null-safe な記述

存在しない可能性のあるオブジェクトを呼び出す前に?を付与して記述します。

```

activity('<アクティビティ名>')?.output.<プロパティ>

```


この記法を利用して、[coalesce()](https://learn.microsoft.com/ja-jp/fabric/data-factory/expression-language#coalesce) とあわせて、スキップされた場合の定数を設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/353e854b-b341-4035-acaa-bd01a6fa522c.png)

結果：

コピーアクティビティがスキップされたｋ0がセットされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/afa53781-6c49-4ad1-8126-94df5eb75ba5.png)



## 実用シーン

### 1. ログの記録

アクティビティの出力を DBに記録しているような場合、なんらかの失敗により、後続のアクティビティがスキップされた場合、以下のような記述で、skip されたことが記録できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8e43624c-4281-41ba-9499-3ea98a062a1c.png)

:::note info

パイプラインのエラーの処理はエラー時の処理にスキップとエラーの分岐をつないであげることで実装します。
[汎用エラー処理](https://learn.microsoft.com/ja-jp/azure/data-factory/tutorial-pipeline-failure-error-handling#generic-error-handling) 

:::

### 2. プロパティの有無チェック

json 値をパイプラインに渡している場合、プロパティが可変である場合があります。このような場合にも安全に対処が可能です。

```json:json

{
  "p1": "プロパティ1",
  "p2": "プロパティ2",
  "p3": "プロパティ3"
}

```
のような値が渡される状況で、p3 のプロパティが存在しない可能性がある場合の記述：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/eb916ba7-40f1-4438-b015-396792ecbf1c.png)

入力値：
```json:json

{
  "p1": "プロパティ1",
  "p2": "プロパティ2"
}

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8bafb053-5d09-4608-b99e-a4a01fb4e1c4.png)


## 参考

https://endjin.com/blog/2021/02/how-to-safely-reference-a-nullable-activity-output-in-synapse-pipelines-and-azure-data-factory
Bella + Canvas 3001 と Comfort Colors 1717：どちらのTシャツが自分に合っている？

ブランド用、あるいはプリントオンデマンドで販売するTシャツを選ぶ際、Bella + Canvas 3001 と Comfort Colors 1717 は非常に人気の高い選択肢です。どちらも高品質なリングスパンコットンを使用していますが、生地の厚みやフィット感、全体的な着心地には明確な違いがあります。では、あなたやあなたの顧客にとって最適なのはどちらでしょうか？

![Bella Canvas 3001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052539/50445708-9b82-46b1-8413-e91f897dc571.jpeg)

生地の重さと肌触り
まず注目したいのは生地の重さです。

[**Bella + Canvas 3001**](https://merchize.com/product/unisex-jersey-short-sleeve-tee-bella-canvas-3001-made-in-us/) は、4.2オンス/平方ヤードの軽量Tシャツです。高密度のリングスパンコットンを使用しており、非常に滑らかでソフトな肌触りが特徴です。

[**Comfort Colors 1717**](https://merchize.com/product/classic-unisex-t-shirt-cc1717/) は、6.1オンス/平方ヤードのヘビーウェイトTシャツで、より厚みがありしっかりとした着心地です。

柔らかく軽いTシャツが好みの人にとって、Comfort Colors 1717 のような厚手のシャツは「硬くてチクチクする」と感じるかもしれません。一方で、しっかりとした生地感が好きな人にとっては、Bella + Canvas 3001 のような薄手のTシャツは「頼りなく感じる」こともあるでしょう。どちらが良いかは人それぞれです。

フィット感と作りの違い
次に注目すべきは、フィット感と構造です。

Bella + Canvas 3001 は、現代的な「リテールフィット」が特徴です。胴体部分がやや長く、袖は短めで、胸元からウエストにかけて自然なラインを描きます。サイドシーム（脇の縫い目）付きで、すっきりとしたシルエットになります。

Comfort Colors 1717 は、ゆったりとしたボックスフィットです。筒状の編み方（チューブラー構造）で作られており、サイドシームがない分、カジュアルでリラックスした印象になります。

スタイリッシュでフィット感のあるシルエットを求める方には Bella + Canvas 3001 が適しています。逆に、リラックス感や動きやすさを重視する場合は Comfort Colors 1717 の方が快適に感じられるでしょう。

誰にどちらがおすすめ？
Tシャツの好みは人によって大きく異なります。ある意味では「ゴルディロックス問題（ちょうどいいバランスの探求）」とも言えるでしょう。

アメリカ西海岸や温暖な地域の顧客には、柔らかくて軽い Bella + Canvas 3001 が好まれる傾向があります。

一方で、アメリカ中西部など寒冷地の顧客には、しっかりとした着心地の Comfort Colors 1717 が人気です。

顧客層が多様である場合や、好みが分かりにくい場合は、両方の選択肢を提供するのが理想的です。

また、体型も重要なポイントです。スリムな人にはフィットタイプのTシャツが似合いますが、体格の大きな人にはボックスフィットの方が快適に感じられることが多いです。市場をよく理解することが、正しい商品選びにつながります。

プリントとの相性（DTG印刷）
もしDTG（ダイレクト・トゥ・ガーメント）プリントを使用する場合、Bella + Canvas 3001 の方が優れた印刷結果を得られる可能性が高いです。糸の密度が高いため表面が滑らかで、インクの定着が良く、カラーが鮮明に出ます。逆に、Comfort Colors 1717 のように生地が粗めなシャツは、細かいデザインの再現に限界が出ることもあります。

まとめ
Bella + Canvas 3001：軽量でソフトな肌触り。モダンで洗練されたシルエットを求める方や、温暖な地域向けにおすすめ。

Comfort Colors 1717：厚手でゆったりとした着心地。ナチュラルな風合いや、耐久性を重視する方に最適。
Source: [**Print on demand**](https://merchize.com/)
アプリ開発、ペンテスト未経験者のOSWA合格体験記

# はじめに
webapp開発、ペネトレーションテストともに未経験の状態からoffsecのLearnOneを受講し、OSWAに合格しました。
OSCPは多くの記事がありますが、OSWAはあまり記事がなかったため、どなたかの参考になればと思い雑に書き残します。

# 筆者の経歴
* 半コンサル半技術者の大卒IT会社員6年目
* ちょっとだけLinux触ったことある
* 開発経験ゼロ
* 情報処理安全確保支援士 は取得済み（XSS, SQLiの名前は知っている程度）

# 学習手段
offsecの公式OSWAモジュールラボ、チャレンジラボ
チャレンジラボは本当に大事です。
3周くらいやりました。
本番は大体チャレンジラボと同じくらいの難易度でした。
チャレンジラボは1周目に自力で解けたものはありませんでした。
すべてdiscordで過去の投稿を見ながらです。
それでも学びは多くあります。

# 総学習時間
大体 5,6時間×90日
攻撃的スキルを学ぶことが初だったため、結構時間をかけた印象です。
当時は業務の閑散期だったのでほぼ毎日5,6時間はやってました。
チャレンジラボは本当に大事です。（2回目）

# テスト結果
70点で合格（合格ライン70点）
５台のマシンに2つずつflagがありますが、3台完答、1台localのみ、1台は足掛かりすら掴めずでした。
合格ラインまでは6時間程度でしたが、そこから12時間近く地獄の無進捗で、諦めてレポート作成に移りました。

この記事を読んでいる方ならご存知かと思いますが、各マシンのflagの場所は次の通りです。
* local：webappの管理者画面に記載
* proof：webappが稼働するサーバのwebディレクトリにtxtファイルで存在（/var/www/htmlなど）

# OSCPとの比較
私自身、現在OSCP勉強中ですが、OSWAはバージョン情報から既知の脆弱性を探して〜のようなアクションがいらない分、やりやすいと思います。
また、OSCPのlocal.txtにあたる内容がproof.txtであり、サーバー内での権限昇格が不要なのも初心者向きだと思います。

# 攻略時の考え方（ちょっとメタい）

## local
localは管理者画面に存在します。
そのため、よく用いられる攻撃手法は次の通りです。
* XSS
* SQLi
* 管理者画面への認証試行

逆にサーバー側に対して何かしらアクションを行うようなXXE、コマンドインジェクション、ディレクトリトラバーサルなどは使わないことが多いです。

管理者が何かを確認するシーンが考えられる（掲示板、ログなど）場合にはXSSでcookieを取ったり、ユーザー追加やPW変更のjavascriptを実行させるなど。


## proof
proofはサーバー側に存在します。
そのため、よく用いられる攻撃手法は次の通りです。
* SQLi
* XXE
* コマンドインジェクション
* ディレクトリトラバーサル
* テンプレートインジェクション
* SSHの認証試行

XSSからサーバーへの足掛かりが得られる可能性は完全に排除してよいのではないでしょうか。
（私が知らないだけで全然あるかもしれませんが）

# 攻略の流れ
流れ自体は意外とシンプルです。
1. ポートスキャン：80以外でhttpが開いているかもしれない。
SSHは基本空いているが一旦無視。
2. ディレクトリ列挙：とにかく列挙しまくる。
最初は少ないリストでいいが、ヒットしたリストを見ている間に大きいリストで調べておくのがおすすめ。
リストは[この辺](https://github.com/danielmiessler/SecLists/tree/master/Discovery/Web-Content "seclist")を使いました。
最初は[common.txt](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/common.txt)、次に[raft-large-directories.txt](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/raft-large-directories.txt)。
largeはとても時間がかかるので最初からやるのはあまりお勧めしません。
3. 入力できる箇所全てに前述の攻撃手法を試す（ゴリ押し）

以上です。
冗談ではなく、ひたすら列挙列挙列挙・・・、入力入力入力・・・

# おすすめツール
### nmap
おすすめというよりポートスキャンで必須
### burp
おすすめというよりwebappに対するテストでは必須（特にrepeater, intruder）
### dirsearch
個人的にはgobusterよりおすすめ
もしかしたらgobusterの方が早い、のようなことはあるかも
見つけたディレクトリに対して、再帰的に探索してくれるので便利です。
```shell:dump
dirsearch -u http://**** -w /usr/share/seclists/web-content/common.txt
```
### sqlmap
POSTのrequest formを丸ごとtxtファイルにして -r オプションで投げれば楽ちん
dbs→tables→dumpの順で徐々に狭めていくのがおすすめ
最初からdumpするととんでもない時間がかかる場合あり
```shell:DB列挙
sqlmap -r request.txt --dbs --batch
```
```shell:テーブル列挙
sqlmap -r request.txt --dbms=mysql -D dbname --tables --batch
```
```shell:dump
sqlmap -r request.txt --dbms=mysql -D dbname -T tablename --dump --batch
```
--batchはユーザーに対する問いを自動でyesにして進めてくれる。
使い方は[このページ](https://www.stationx.net/sqlmap-cheat-sheet/)がおすすめ
### 

他にもXSStrikeがおすすめという記事を見かけましたが、私には使いこなせませんでした。

# 最後に
OSCPは分かりませんが、OSWAはいい時間からの開始がありませんでした。
朝4時から or 夕方16時からだった気がします。
生活リズムが乱れるので気をつけてください。
正直無理な時はとことん無理です。
私は最初の3時間進捗無しで絶望しましたが、攻略マシンを変えたら一瞬で合格ラインまで突っ走れました。
ある程度やって進捗なければマシンを変えた方がいいと思います。

# 今後の展望
OSWA後、OSWP、CEH MASTERは取得できたので、そろそろOSCPを目指します。
ともにtry harderしましょう・・・
PHPのプレースホルダとは

## 目的
phpで使うブレースホルダが良くわからなかったのでまとめた

## ブレースホルダとは
SQL文の中にPHPの変数を直接書くと、悪意のあるユーザーからdbを操作される可能性がある。
```php:ダメな例
$sql = "SELECT * FROM user WHERE name= '$name'";

```

## プレースホルダを使用する
```php
$sql = "SELECT * FROM user WHERE name= :name";
```

```php
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$bands = $stmt->fetchAll(PDO::FETCH_ASSOC);//表示
```

$parmsは事前に
```
$parms = [];
```
で定義すると空でも使える。




## 参考サイト
https://qiita.com/pito555/items/73ea74114a59d7ee2dd2
【備忘録】AWS Academy Learner Lab でAWS CLIの認証を通す

# はじめに
`Learner Lab`で`ECR`に自作イメージを`push`したいが、`AWS CLI`を使うための`IAMユーザー`が作成出来ない時の対処法です。

# 認証手順
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/959995a9-0736-465c-a830-e80353d4dd3c.png)
- ①起動メニュー右上にある**AWS Details**をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/57c14316-176e-4b14-a5a5-1acabcef2e17.png)
- ②`AWS CLI`右横にある**Showボタン**をクリックする。
- 以下の文字列が3種類記載されている
    - aws_access_key_id
    - aws_secret_access_key
    - aws_session_token
- ③認証情報を以下のコマンドで設定する
`user/.aws/credintials`に登録されている
```console
aws configure
```
```console
aws configure set aws_session_token 発行されたセッショントークン
```

- ④認証が正しく通ったか確認する
```console
aws sts get-caller-identity
```
ユーザーID等が含まれたJSONが返ってきたら正しく認証出来ている
なぜ、アジャイル開発はカオス化してしまうのか？

先日、とあるITコンサルタントの人が、こんなことを言っていた

**「今の時代は、アジャイル開発が主流です。ウォーターフォールなんて時代遅れですよ。」**

本当に、そうなのだろうか？

今まで様々なプロジェクトを見てきたが、アジャイル開発ほど、抽象的で、曖昧で、ファジーな開発手法を見たことがない。むしろ、ウォーターフォール開発のような決まりきったルールのない開発手法を「アジャイル開発」と呼んでいるような気がする。

一方で、アジャイル開発を採用する流れを確かに感じている。特に、スタートアップやベンチャー系の新規プロダクトは、アジャイル開発を採用することが多いだろう。しかし、「そうだ、京都に行こう！」というノリでアジャイル開発がうまくいっている現場を見たことがない。

私が、これまで見てきた開発現場（自分が参画したものもあれば、参画してないものも含む）のアジャイル開発は、悪い意味で曖昧で、悪い意味でいい加減、なカオスな現場が一定数あった。

ということで、この記事でアジャイルがカオス化する理由を書き連ねようと思う。この記事を読んで頂き、何か当てはまることがある方は、是非とも改善してみてほしい。

## 理由①「基礎を知らない行き過ぎた自由」
アジャイルのことを「自由に開発できるやつ」と捉えている人が多いだろう。間違いだ。何事もそうだろうが、「基礎」は大切である。アジャイル開発にも一定のセオリーがある。そして、このセオリーを勉強していない人が多すぎる。

「アジャイル開発＝スクラム開発」と誤解している人すら散見する。私は、アジャイル開発の中に、スクラム開発・XP（エクストリームプログラミング）・FDD（機能駆動型開発）のような各種開発手法があるという認識である。と言う風な基礎を知らない。

スクラム開発を例に挙げても、たくさ〜んの単語を勉強する必要がある。
- プロダクトバックログアイテム
- スプリントバックログアイテム
- スクラムマスター
- プロダクトオーナー
- スプリント
- プロダクトバックログリファインメント

基礎あっての応用であり、なんとなくバックログの概念だけでどうにかしようとしていると、気づくとカオスになってしまうのだろう。一方で、「アジャイル開発は、自分たちの好きなようにルールを作ってもいいんだ！」という主張自体は正しいとも思う。[アジャイルソフトウェア開発宣言](https://agilemanifesto.org/iso/ja/manifesto.html)の中にも以下のような文言がある。

> チームがもっと効率を高めることができるかを定期的に振り返り、それに基づいて自分たちのやり方を最適に調整します。

つまり、自分たちの好きなように最適化することは間違っていない。とはいえ、ある程度のフレームワークの中で自己流を出さなければいけないのだろう。テニスのフォームを自己流ですると失敗するみたいなことに似ているような気がする。

まだアジャイルに慣れていない・アジャイルの基礎を知らない人が多いチームは、「アジャイル開発ってなんだっけ？」という時間を作ってみるのは、とても良いのではないかと思う。

## 理由②「アジャイルをただの開発理論として消化している」
何言ってんだって話だが、要は「**アジャイル開発は、広義のマネジメント論・組織論でしょ？**」と私は言いたい。タスク管理をいい感じにすればいい訳でもなく、スプリントを切っていい感じにMTGをこなしておけばいい訳ではない。

働く人は人間であり、完全合理主義ではない限定合理的感情人（[参考](https://www.lmi.ne.jp/about/me/laboratory/)）なのである。まさに、この部分を円滑に進めるのが、スクラムマスターのような立場であり、スクラムマスターのトレーニングを真剣に進めなければならない。

「心理的安全性」「ティール組織」「サーヴァントリーダーシップ」など色々な組織論を学習する必要があると考えている。ちなみに、こんな研修もある。（→先に言っておくが、回し者ではない。むしろ、アフィリエイトのリンクがあるならば欲しい笑）

Registered Scrum Master® Training（2dayのコース）

https://scruminc.jp/training/master/

ということで、1エンジニアとして捉えるのではなく、組織全体をマネージするHRのような立場からチームを考えてみると良いでしょう！

## 理由③「POが、顧客の声を拾えていない」
棘ある言葉で申し訳ないが、たまに感じることがある。POがプロジェクトマネージャー（PjM）になっている現場をちらほらと見たことがある。個人的な感覚だが、POはプロダクトマネージャー（PdM）の要素の方が強いと思っている。

POが、なぜかタスク管理やピープルマネジメントのようなことをしていて、どこからともなく上がってきた追加機能を意味もなく作って、気づいたら「その機能、誰も使ってなくない？」みたいなことは、よくあると思う。結果として、疲弊するのは現場のエンジニアである。気付かぬ内に大量のタスクを抱え、気づけばタスクボードが大量のタスクで溢れている。

だからこそ、POはよりPdMの思想を強くもち、本当に必要な機能とは何か？どう実装するべきか？を考えた方がいいと思う。

## まとめ
以上、「なぜ、アジャイル開発はカオス化してしまうのか？」という話でした。これだけ偉そうに書かせてもらったが、「じゃあ、お前できんのか？」と言われたら、「たぶん、、？」くらいの自信でしか返答できない（笑）

開発ってむずかし〜〜。たんたん。

## 宣伝
Organizationsやってます。

https://qiita.com/organizations/raretech
DMARCレポートのparseをGoogle Colabとparsedmarcで

# 概要
* DMARCレポートを、可視化は後から考えるとしてひとまずExcelでいいから見たい
* ひとまず動いたメモ
* parseはparsedmarcを使用
* 環境はGoogle Colabを使用

# メモ
# Google Colab
[Google Colab](https://colab.research.google.com/)を開いて、ノートブックを新規作成

## インストール
```
pip install parsedmarc
```
## モジュール読み込み
```
import parsedmarc
```
## DMARCレポートをアップロード
DMARCレポート（圧縮されたままで良い）をアップロードする。
![colab00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255373/9fea7eaf-8ec3-4fcc-8f04-f1eb140cc5f0.png)

## DMARCレポートのparse
アップロードしたDMARCレポートのパスを、ファイル右のメニューからコピーする。
![colab01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255373/89cd23ac-68f1-4330-8635-114df0af5c62.png)
その後、コピーしたパスを指定してparseを実行する。
```
rslt = parsedmarc.parse_aggregate_report_file("コピーしたパス")
```

## CSV出力
適当な出力ファイル名を */content/* の後に付けて、parseの結果（ここでは*rslt*）を指定してCSV出力。
```
parsedmarc.append_csv("/content/出力したいファイル名", parsedmarc.parsed_aggregate_reports_to_csv(rslt))
```

## CSVダウンロード
出力されたCSVファイル右のメニューからダウンロード。
![colab02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255373/c6db90b3-698e-41c6-9080-9168a6f444f2.png)

# 後書き
ひとつずつ見ていられないので可視化するのが普通でしょうが、とっかかりとしてひとまず「ああ、こういうものなのね」と見るために。それならxmlのままでもいいじゃないか、という気もしますが。

# おまけ
不正確かもしれないけれど「DMARCってこういうこと？」と現状の理解のベン図。それはさすがに違い過ぎやろ、というツッコミ歓迎。
![DMARC_Venn_diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255373/eacf6903-554e-49f3-a1f5-07611c82a4ec.png)
結構面倒なMySQLのバックアップmysqldump+user+password+host更に、リストア

MySQLのデータベースをサーバ間で取るには、幾つかの手順が必要なので覚書。
結果は下記の様なコマンドに。
```
mysqldump --defaults-extra-file=/etc/sql.cnf --no-tablespaces --single-transaction データベース名 > backup.sql
```
ユーザ名、パスワードは直書きせず、sql.cnf等のファイル作成、パーミッションを600等に設定。
--defaults-extra-file=/etc/sql.cnfの内容は以下に。
```
[client]
user = {user}
password = {password}
host = {hostip}
```
--single-transaction オプションは InnobDB メインな DBでデータの整合性保つように追加しています。

tabelspaces とは、MySQL 5.6 から加わった機能で、--no-tablespaces オプションを加えると大丈夫のようです。
--defaults-extra-fileはmysqldumpのすぐ後に記述しないとエラー。
またこれらの実行を可能にするには、元サーバのMySQLに下記の設定が必要です。
```
mysql -u root -p
//ログインして
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `データベース名`.* TO 'user'@'hostip';
mysql> FLUSH PRIVILEGES;
//上記実行で外部からの接続許可。
//phpMyAdminでSQL実行でも可能。
```

```
vi bkup.sh
#! /bin/sh
mysqldump --defaults-extra-file=/etc/sql.cnf --no-tablespaces --single-transaction データベース名 > backup.sql
shellに実行権限付与
chmod +x chatkww_bkup.sh
//下記の様にshell実行
./chatkww_bkup.sh
```
backup.sqlが存在すればOKです。
後は、crontabにバックアップスケジュールを記述して完了。
```
crontab -e
00 23 * * * ./bkup.sh
```
以上MySQLの定期的な外部バックアップです。
更に、バックアップ側のサーバにリストア！！
phpMyAdmin等でデーベース作成。
```
mysql -u root -p
mysql> -u root -pパスワード データベース名 < backup.sql
```
backup.sqlには。テーブルをDROP TABLE IF EXISTS テーブル名、CREATE TABLE テーブル名　を実行するので、内容は更新されます。
shellでも下記の様に記述し、crontabにてバックアップサーバに最新データに更新する。
```
#!/bin/bash
mysql -u root -pパスワード データベース名 < backup.sql
echo "Restore completed"
```
zipからcsvファイル

```
package your.package.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class S3ZipCsvReader {

    public static <T> List<T> readCsvFromZippedStream(
            InputStream zipInputStream,
            String targetCsvName,
            Class<T> dtoClass
    ) {
        try (ZipInputStream zis = new ZipInputStream(zipInputStream, StandardCharsets.UTF_8)) {
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                if (entry.getName().equals(targetCsvName)) {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(zis, StandardCharsets.UTF_8))) {
                        return CsvReaderUtils.readCsv(reader, dtoClass);
                    }
                }
            }
            throw new RuntimeException("ZIP内にCSVファイル（" + targetCsvName + "）が見つかりませんでした。");
        } catch (Exception e) {
            throw new RuntimeException("ZIPストリームからCSV読み込み中にエラーが発生しました", e);
        }
    }
}
```
1 はどこにある？

今回はPaizaの「配列の中の1の位置を全部出す問題」に挑戦！

前回学んだ `entries()` を使ってみたけど、順番とインデックスのズレでちょっとつまづいた…(´;ω;｀)

<br>

## 問題概要

- N個の整数が与えられる
- a_1 を 1番目とし、配列に必ず1が含まれる
- 1 がある位置を先頭から順に改行区切りで出力

<br>


入力例：

    5
    5 3 1 3 5

出力例：

    3

<br>

https://paiza.jp/works/mondai/loop_problems2/loop_problems2__seq_one

<br><br><br>

## ❌NG例
```js
const rl = require('readline').createInterface({input:process.stdin});

const lines = [];

rl.on('line', (input) => {
    lines.push(input);
});


rl.on('close', () => {
    const N = Number(lines[0]);
    const nums =  lines[1].split(' ').map(Number);
    
    
    for(const [value, index] of nums.entries()){
        if(value === 1){
            console.log(index);
        }
    }
});
```
→ インデックスと値の取り方が逆！さらに0始まりのまま出力してるからズレる。

<br><br>

## ✅OK例
```js
for(const [index, value] of nums.entries()){
    if(value === 1){
        console.log(index + 1);
    }
}
```
→ こっちは正しく[インデックス, 値]を取って「+1」して出力。バッチリ！

<br>

## ✅OK例（王道forループ）
```js
for(let i = 0; i < N; i++){
    if(a[i] === 1){
        console.log(i + 1);
    }
}
```
→ シンプルで初心者にも分かりやすい！

<br><br>

## 📝気づきメモ

 - `entries()` は `[index, value]` の順番で受け取る。

- 配列のインデックスは0始まりだから、答えは必ず「+1」すること！

- 基本の for ループも使いこなせるようにする。


<br><br><br>[僕の失敗談(´;ω;｀)と解決法🐈](https://paizabeginner.wordpress.com/2025/06/12/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a1-%e3%81%af%e3%81%a9%e3%81%93%e3%81%ab%e3%81%82%e3%82%8b%ef%bc%9f/)