Haskell PersistentでUpperCaseなテーブルに対応する方法

Tech > Haskell > データベース

大文字とアンスコで作られたテーブルに lowerCaseSetings アクセスすると、 テーブルが見つからない とOracleで叱られるパターンがあるというかあった、アクセス時にテーブル名に引用符を付けずにいけばアクセスできそうだったがやり方が分からなかったので、あきらめてテーブル名を変えてアクセスできる方法をとった。

そこでPersistentを利用してデータベースマイグレーションをかけた場合に、modelファイルにキャメルでかかれたエンテティ情報をデータベーステーブル名へ変換生成する方法を決める関数が2つある

model例

OraEmail
    email Text
    userId OraUserId Maybe
    ...

lowerCaseSettings

この関数はキャメル部分をアンスコ(_)でつけてすべて小文字で生成する

CREATE TABLE ora_email (email, user_id....

upperCaseSettings

この関数はそのままキャメルで生成する

CREATE TABLE OraEmail (email, userId....

マイグレーションから作成して利用していく分には問題ないが、既存のデータベースでテーブル名が全部大文字で作成されている場合、どちらもつかえない

大文字のテーブルに対応する

今のところ調査が中途半端で、シーケンス名や制約名などがマイグレーションで作成した場合、一部小文字になってしまうが、 マイグレーションはしない という前提であればデータベースへのアクセスは可能

fullUpperCaseSettingsの作成

オリジナルでupperCaseSettingsをパクって似たようなものをつくる、TemplateHaskellとQuasiQuoteで生成されるので外部からModel.hsへImportして使えるようにする

{-# LANGUAGE OverloadedStrings #-}

module Ext.Persist
  ( fullUpperCaseSettings
  )
where

import Data.Char
import qualified Data.Text as T
import Database.Persist.Quasi

fullUpperCaseSettings :: PersistSettings
fullUpperCaseSettings = PersistSettings
  { psToDBName =
    let go c
          | isUpper c = T.pack ['_', toUpper c]
          | otherwise = T.singleton (toUpper c)
    in T.dropWhile (=='_') . T.concatMap go
  , psStrictFields = True
  , psIdName = "ID"
  }

そして、Importしつつこの関数をpersistFileWith関数へ渡してやる

...
import Ext.Persist
...
share [mkPersist sqlSettings, mkMigrate "migrateAll"]
    $(persistFileWith fullUpperCaseSettings "config/models.persistentmodels")
...

そうすると

CREATE TABLE ORA_EMAIL (EMAIL, USER_ID....

のようなテーブルにアクセスできるようになる

Github

コードはこちら

Posted on 2021-03-20 06:43:41

はじめまして

お茶の国静岡で、焼酎のお茶割なんか罰当たりで飲んだことはありません、常に一番搾りを嗜む静岡極東のBBQerです、最近まわりのエンジニアの方々がお料理を上手にやっている姿を恨めしそうに横目に見ながら、軟骨ピリ辛チクワを食べています、みなさんよろしく。

Posted

Amazon

tags

日本酒池 広井酒店 やがら やっぱた 刺身 丸干し 東京マラソン fpm php82 servant thread spawn Rust Oracle Linux 8 microcode firmware linux openzfs zfs gitea 麒麟 真野鶴 金鶴 日本酒 docker oracle pod podman cli virtualbox VirtualBox epub mobi calibre mask lens ワンライナー php redmine Linux Oracle Map OMap omap map BBQ カテゴリ管理 カテゴリ timestamp date oracle database string 麦焼酎 ダービー process 磨き蒸留 広井酒店、日本酒 芋焼酎 焼酎 ゆるキャン 広井酒店、日本酒池 spring framework java persistent spring session session spring hdbc-odbc persistent-odbc odbc day utctime スィート レマンの森 elm初期化 elm バイク xlr80 esqueleto database xl2tpd strongswan vpn l2tp ipsec 正月 ゲーム grub nginx systemctl portage 豚骨 圧力鍋 yesod-auth-hashdb yesod-auth yesod