database_name
をデータベース名に変えてください。
SELECT `table_name` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'database_name';
database_name
をデータベース名に変えてください。
SELECT `table_name` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'database_name';
[]byte
型を使わないstring
型や json.RawMessage
型を使うGoのwebアプリケーションで、go-sql-driver/mysqlの interpolateParams=true
オプションを有効にしてテストを回したら、以下のようなエラーでテストが落ちた。
interpolateParams=true
はプレースホルダ置換を有効にするオプションである*1。
Cannot create a JSON value from a string with CHARACTER SET 'binary'.
アプリケーションのコードは interpolateParams=true
を指定しただけで他の箇所は書き換えていない。MySQLと通信するときのcharacter setに binary
を指定した覚えは全くない。何が起こっていたのか?
DBの行をマップしているstructの構造をかいつまんで書くと以下の通り。JSON型のカラムを書き込むところでエラーになっていた。
type User struct { Id string `db:"id"` Data JsonColumn `db:"data"` // JSON NOT NULL } // JsonColumn は driver.Valuer, sql.Scanner を実装している // 内部的に json.Marshal, json.Unmarshal を呼んでいる type JsonColumn []byte
出てきたエラーメッセージで検索してみると以下のissueがヒットした。
JSON型のカラムをやり取りするときは []byte
型ではなく string
型や json.RawMessage
型を使うようにするといいらしい。
ということで、筆者が関わっているプロダクトではstructのフィールドの型を自由に調整できるのでこれで解決しました。
これだけで記事を終わっても備忘録*2としてはいいだろうけど、ついでなのでプレースホルダ置換を有効にしてエラーになったとき何が起こっていたのか見てみる。
mysqlConn
structの interpolateParams
メソッドの []byte
型に対する処理を読んでみると、文字列リテラルの前に _binary
というのを書いていて、いかにもバイナリにしていそう。
これはイントロデューサというもので、文字列リテラルのcharacter setを指示しているらしい。謎が解けましたね。
utm_campaign=ブルアカぬいぐるみ0901まで
— うたがわきき (@utgwkk) 2023年8月23日
部屋の容積は有限、置きたいものは無限、次にやることは?
しました。
聞いたトークのメモはScrapboxにまとめてあります。以下では特におもしろかったトピックを取り上げます。
Rubyの正規表現の改善について、ReDoSを回避できるようにするための取り組みが尊いというのと、正規表現の知らない機能が意外と多い!! というのが両立していました。現実の正規表現エンジンは、オートマトンの講義の文脈で習う「正規表現」よりも遥かに表現力が高くて考慮すべき点が多そうだけど、それらをちゃんとケアして現実の問題に反映していて最高。
Rubyのプロファイリング結果の可視化のためにFirefox Profilerを使うという発想がおもしろかったです。可視化は確かにノウハウのあるところに乗っかるほうが、自分でイチから作るよりも早くて見やすくできそう。個人的には、最近はOpenTelemetryによるトレーシング文脈での可視化が気になっています。
言語自体の自由度の高さと最適化しやすさのトレードオフみたいなのがありそうで、特にRubyだと既存のクラスに自由にメソッドを追加・オーバーライドできるのが大変そうでした。絶対やらないと思うけど理論的にはできてしまうのでちゃんとケアする、とか……。
Rubyの場合は、言語処理系や周辺エコシステムに貢献している人が身近に・国内にたくさんいて可視化されやすい、というのが他の言語から見たときにけっこう新鮮に見える、というのを実感しました。RubyKaigiで発表して終わり、ではなく続けて改善を進めていたり、RubyKaigiの発表に影響されて物作りを始めていたりしてよい流れができていそう。目の前にMatzがいて発表ごとにコメントしてもらえてよさそう。
カンファレンスに参加して学びがあって最高、というのはもちろんあるけど、カンファレンスのその後に焦点を当てることがなかなかない気がしていて、他のカンファレンスでも似たような取り組みがあったら参加したいですね。
絶対もうあるでしょう、と思いつつも書きました。go-sql-driver/mysql を使っているのでlibmysqlclientが入っていなくても動くと思います。
mysql
コマンドでホスト名・ポート番号を指定して接続するのと同じコマンドライン引数が使えます。ほかのコマンドライン引数は必要になったら対応します。
$ go-mysqlping -h127.0.0.1 -P3306 -uroot -ppassword
1秒おきにDBアクセスしつつcontextでキャンセルできるようにする、みたいなのを初めて書いたけど意外と書けるものですね。time.Tickという関数があることは知っているけど、最初にアクセスするときに1秒待ってほしくないので手作りしています*1。goroutineがリークしていたら教えてください。
コミックマーケット102の告知です。
最低限ここだけ読んでもらえれば十分です。
「わくわく活動報告 Go編」という薄い本が出ます。このブログでもいくつか記事を書いていると思いますが、最近書いたGoのコードや便利グッズの話を軽くまとめた本になります。
頒布価格は100円です。
C100で頒布した「create-react-appの中身を見る」も頒布する予定です。
最近のcreate-react-appの動向はどうなのか、という向きもあると思いますが、フロントエンドツールチェインについてなんとなく知る機会ということでいかがでしょうか*1。
id:Pasta-K さんの「2023年の良かった新作マンガ Ver.C102」が無料頒布される予定です。詳しくは当該記事をどうぞ。
各種クレジットカード (Visa/Mastercard/Amex/JCB/Diners Club/Discover) のタッチ決済に対応しています。現金支払いにも対応していますが、キャッシュレス支払いのほうが後から記録を正確に見返しやすいのでありがたいです。
*1:個人的には、在庫が掃けると嬉しい!!