Pool de conexões de banco de dados simultâneas em Haskell
Eu sou um programador Java que aprende Haskell.
Eu trabalho em um pequeno aplicativo web que usa Happstack e fala com um banco de dados via HDBC.
eu escreviselecionar eexec funções e eu usá-los assim:
module Main where
import Control.Exception (throw)
import Database.HDBC
import Database.HDBC.Sqlite3 -- just for this example, I use MySQL in production
main = do
exec "CREATE TABLE IF NOT EXISTS users (name VARCHAR(80) NOT NULL)" []
exec "INSERT INTO users VALUES ('John')" []
exec "INSERT INTO users VALUES ('Rick')" []
rows <- select "SELECT name FROM users" []
let toS x = (fromSql x)::String
let names = map (toS . head) rows
print names
Muito simples como você vê. Há siminquerir, params eresultado.
Criação de conexão e commit / rollback estão escondidos dentro de select e exec.
Isso é bom, não quero me importar com isso no meu código "lógico".
exec :: String -> [SqlValue] -> IO Integer
exec query params = withDb $ \c -> run c query params
select :: String -> [SqlValue] -> IO [[SqlValue]]
select query params = withDb $ \c -> quickQuery' c query params
withDb :: (Connection -> IO a) -> IO a
withDb f = do
conn <- handleSqlError $ connectSqlite3 "users.db"
catchSql
(do r <- f conn
commit conn
disconnect conn
return r)
(\e@(SqlError _ _ m) -> do
rollback conn
disconnect conn
throw e)
Pontos ruins:
QUESTÃO 1: como introduzir um pool de conexões com algum número definido (min, max) de conexões simultâneas, para que as conexões sejam reutilizadas entre as chamadas select / exec?
QUESTÃO 2: Como tornar a string "users.db" configurável? (Como movê-lo para o código do cliente?)
Deve ser um recurso transparente: o código do usuário não deve exigir o tratamento / liberação explícito da conexão.