Tôi là một lập trình viên Java học Haskell.
Tôi làm việc trên một ứng dụng web nhỏ sử dụng Happstack và trao đổi với cơ sở dữ liệu thông qua HDBC.Đồng thời kết nối DB pool trong Haskell
Tôi đã viết chọn và exec chức năng và tôi sử dụng chúng như thế này:
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
Rất đơn giản như bạn thấy. Có truy vấn, thông số và kết quả.
Tạo kết nối và công cụ cam kết/cuộn lùi được ẩn bên trong chọn và thực thi.
Điều này là tốt, tôi không muốn quan tâm đến nó trong mã "logic" của tôi.
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)
(\[email protected](SqlError _ _ m) -> do
rollback conn
disconnect conn
throw e)
điểm xấu:
- một kết nối mới luôn tạo ra cho mỗi cuộc gọi - điều này giết chết hiệu suất trên tải nặng
- DB url "users.db" là hardcoded - Tôi không thể sử dụng lại các chức năng này trên các dự án khác bằng cách chỉnh sửa
CÂU HỎI 1: cách giới thiệu một nhóm kết nối wi th một số được xác định (min, max) số lượng kết nối đồng thời, do đó, các kết nối sẽ được tái sử dụng giữa các cuộc gọi select/exec?
CÂU HỎI 2: Cách đặt cấu hình chuỗi "users.db"? (Làm thế nào để chuyển nó sang mã máy khách?)
Nó phải là một tính năng trong suốt: mã người dùng không nên yêu cầu xử lý/giải phóng kết nối rõ ràng.
Tôi không có câu trả lời đầy đủ cho bạn, nhưng vấn đề của bạn là bạn đã trừu tượng hóa kết nối không chính xác. Bạn có thể muốn đặt nó trong một cấu trúc giống như Reader, để nó có thể được truyền cho mỗi truy vấn. – jrockway
Hmm, các hoạt động SQL đều bị mắc kẹt trong đơn nguyên 'IO', vì vậy có lẽ' ReaderT IO'? Nghe có vẻ hợp lý. – ephemient