Slide 1

Slide 1 text

ちょこっとdive gorm.DB.Updates() aroon

Slide 2

Slide 2 text

予防線(???) ● 実はこんなバグがあって・・・・! ● 実はこんな挙動があって・・・・! ではないです。 多分見つけてたらタイトルが もうちょい違います😇😇😇

Slide 3

Slide 3 text

自己紹介 ● aroon ● Gopher暦 半年くらい

Slide 4

Slide 4 text

クイズです!!

Slide 5

Slide 5 text

下記3つの選択肢のうち、ageがnullに更新される書き方はど れでしょうか?

Slide 6

Slide 6 text

正解は・・・・ 2と3です!

Slide 7

Slide 7 text

gormのUpdatesメソッド with null 仕様 nullableカラムに対してnullで更新しようとする場合・・・ ● structを渡した場合、基本nullや0は無視される ● mapであれば更新対象にしてくれる ● structを利用する場合、Selectで指定すれば更新対象 にしてくれる

Slide 8

Slide 8 text

さらにクイズです!!

Slide 9

Slide 9 text

gormはどのようにして そんな仕様を実現してるんで しょうか?

Slide 10

Slide 10 text

Thinking Time

Slide 11

Slide 11 text

僕なりの回答は・・・・(というか今日の内容は) ● reflectパッケージの各種メソッドの叡智を 用いて ● ユーザー入力の値を丹念に場合わけし ● その結果をベースにクエリを構築している

Slide 12

Slide 12 text

ちょっとコードを読んで 「どこでそんな処理してんの?」 を見にいきます!

Slide 13

Slide 13 text

Let’s GO !!

Slide 14

Slide 14 text

というわけでまずはUpdatesにGo !! 罠である

Slide 15

Slide 15 text

こんな感じ processor構造体のポインタを返している だけである。

Slide 16

Slide 16 text

Executeについても・・・・

Slide 17

Slide 17 text

読み進めていくと・・・ p.fnsからメソッド取り出して適用してる・・・!?

Slide 18

Slide 18 text

どのタイミングでp.fns構造体に詰めたんだ・・・?

Slide 19

Slide 19 text

そう。Openメソッドです。 というわけで Openを読み進めていくと、 コールバックを登録するよ!みたいなメソッドにたどり着く。

Slide 20

Slide 20 text

Updateメソッドがいるぞ・・・!

Slide 21

Slide 21 text

上から読み進めると・・・ ● ConvertToAssignmentsにてついにお目当てのコードに辿り着く・・・! ● ここからはリアルコードに行きます・・・! ○ https://github.com/go-gorm/gorm/blob/v1.25.12/callbacks/update.go#L260

Slide 22

Slide 22 text

まとめ ● gormはOpenメソッドで ○ 各種構造体を初期化している ○ Update, Queryなどの関数を登録している ● Updateメソッド内部の ○ ConvertToAssignmentsメソッドにて ■ mapか構造体かでsetするかどうかを決定している ■ structの際は、Nilや0の場合にsetしない ○ と判定している