2017年10月9日月曜日

Yesodのsettings.ymlとセッティング

Yesodの設定


三連休も結婚式だの、2次会からただの飲み会まで、昼からやりつづけた結果、夜にはバイオレンスおじさんが登場し出すし、それを押さえつける暴力おじさんとか、もう結構ひどい有様でだいぶウケたんだけど、Yesodのsettings.ymlです

いやぁつかれましたな

Databaseの設定


settings.ymlのdatabaseセクションにかかれているのがそれ、これはDatabase.Persist.MySQL.ConnectInfoにハマる
database:
  user:     "_env:MYSQL_USER:karky7"
  password: "_env:MYSQL_PASSWORD:hongani"
  host:     "_env:MYSQL_HOST:localhost"
  port:     "_env:MYSQL_PORT:3306"
  path:     "_env:MYSQL_SOCK:/var/run/mysqld/mysqld.sock"
  # See config/test-settings.yml for an override during tests
  database: "_env:MYSQL_DATABASE:hongani"
  poolsize: "_env:MYSQL_POOLSIZE:10"

で、これがSettings.hsのAppSettingsに読み込まれるのでHandlerの中でこうやって使える。
...
    master <- getYesod
    let dbconf = myConnInfo $ appDatabaseConf $ appSettings master
...

ここで帰ってくるdbconfの型はConnectInfo型でそれからsettings.ymlに書かれているそれぞれの値を取得するには
...
    host = connectHost dbconf,
    user = connectUser dbconf,
    passwd = connectPassword dbconf,
    db = connectDatabase dbconf,
    port = (fromIntegral(connectPort dbconf) :: Int),
    socket = connectPath dbconf
...

こうやって取れる、ちなみにMySQLのConnectInfo型は
data ConnectInfo
  = ConnectInfo {
      connectHost :: String,
      connectPort :: GHC.Word.Word16,
      connectUser :: String,
      connectPassword :: String,
      connectDatabase :: String,
      connectOptions :: [Database.MySQL.Base.Types.Option],
      connectPath :: FilePath,
      connectSSL :: Maybe SSLInfo
    }
で定義されてる。

_envってなんだよ


settings.ymlの中の「_env:XXX:」見たいな書き方
database:
  ...
  path:     "_env:MYSQL_SOCK:/var/run/mysqld/mysqld.sock"
  ...

これは環境変数を利用する書き方、要するに上の例だと環境変数MYSQL_SOCKが定義してあったら、それを使ってそうじゃないなら/var/run/mysqld/mysqld.sockを使うよって意味。
~/Code/hongani $ export MYSQL_SOCK=/var/tmp/mysqld.sock
~/Code/hongani $ stack exec -- yesod devel
Yesod devel server. Enter 'quit' or hit Ctrl-C to quit.
Application can be accessed at:

http://localhost:3000
https://localhost:3443
If you wish to test https capabilities, you should set the following variable:
  export APPROOT=https://localhost:3443
...

こんな感じ

settings.ymlに設定を追加する方法


settings.ymlへ変数の追加
...
# Upload files store directory
image-dir: "/home/cuomo/files/"
...

Settings.hsのAppSettingへ登録

最初にAppSettingsへ変数を追加する

data AppSettings = AppSettings
    { appStaticDir              :: String
    -- ^ Directory from which to serve static files.
    , appDatabaseConf           :: MySQLConf
    -- ^ Configuration settings for accessing the database.
    , appRoot                   :: Maybe Text
    -- ^ Base for all generated URLs. If @Nothing@, determined
    -- from the request headers.
    , appHost                   :: HostPreference
    -- ^ Host/interface the server should bind to.
    , appPort                   :: Int
    ...
    ...
    , appImageDir               :: Text
    -- ^ Image Stored Dir <==== ここら
    , appAnalytics              :: Maybe Text
    -- ^ Google Analytics code
    , appAuthDummyLogin         :: Bool
    -- ^ Indicate if auth dummy login should be enabled.
}

次にjsonのparseに追加する、「.:」は必ず値がある場合で、「.:?」はオプション値の場合の書き方。
...
instance FromJSON AppSettings where
    parseJSON = withObject "AppSettings" $ \o -> do
    ...
    appImageDir               <- o .:  "image-dir"
    ...
...

これでHandlerで使えるようになる
...
master <- getYesod
let imgDir = appImageDir $ appSettings master
...

以上、二日酔いから復旧中です...

0 件のコメント:

コメントを投稿