HRRからPostgreSQL操作してみた【Part2】

2019-03-20 programming Haskell, HRR

今回はHRRが自動で設定するデータ型を変更する方法をまとめます. 例として, PostgreSQLのintegerがデフォルトでInt32に設定されてしまうのをIntで上書きしてみます.

前回の復習

前回は,

  • PostgreSQLのDockerコンテナを用意
  • テーブルに対応したデータ型をHRRに生成してもらう
  • HRRからDBを操作してみる

ということをやりました. 今回はちょっと細かめの話題です.

やりたいこと

前回HRRが生成したCountry型をもう一度見てみましょう.

data Country
  = Country {Entity.Country.id :: !GHC.Int.Int32,
             countryName :: !String}

主キーであるidカラムのデータ型がInt32になっています. これをIntにするのが, 今回やりたいことです.

方法

Template HaskellによってCountry型を生成しているコードを修正します.

-- 前回(抜粋)

import Database.HDBC.Query.TH          (defineTableFromDB)
import Database.HDBC.Schema.PostgreSQL (driverPostgreSQL)
import DB                              (connectPG)
import GHC.Generics                    (Generic)

$(defineTableFromDB
    connectPG
    driverPostgreSQL
    "public"
    "country"
    [''Show, ''Generic])
-- 今回(抜粋)

import Database.HDBC.Query.TH          (defineTableFromDB') -- 変更
import Database.HDBC.Schema.PostgreSQL (driverPostgreSQL)
import DB                              (connectPG)
import GHC.Generics                    (Generic)

$(defineTableFromDB'
    connectPG
    driverPostgreSQL
    "public"
    "country"
    [("id", [t|Int|])] -- 追加
    [''Show, ''Generic])

これだけです. カラムのデータ型が指定できるdefineTableFromDB'という関数を使えばいいだけでした.

試したけどうまくいかなかった方法

Haskell入門にはドライバーで設定する方法が書かれていました. それは次のような感じです.

$(defineTableFromDB
    connectPG
    driverPostgreSQL { typeMap = [("integer", [t|Int|])] }
    "public"
    "country"
    [''Show, ''Generic])

これなら, 「PostgreSQLのinteger型を一括でHaskellのInt型に設定できるじゃーん」と思ったのですが, ダメでした.

どうしてうまくいかないのか, 理由はわかりません…