{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module Database.Sql.Simple.MySQL ( MySQL(..) , ConnectInfo(..) , mySQL , module Data.Default.Class , QueryResultsN(..) ) where import Control.Applicative import Control.Monad import qualified Data.Text.Encoding as T import Data.Typeable import Data.Word import Database.Sql.Simple.Internal import qualified Database.MySQL.Simple as MySQL import qualified Database.MySQL.Simple.Types as MySQL import qualified Database.MySQL.Simple.Param as MySQL import qualified Database.MySQL.Simple.Result as MySQL import qualified Database.MySQL.Simple.QueryParams as MySQL import qualified Database.MySQL.Simple.QueryResults as MySQL import qualified Database.MySQL.Base as B import Data.Default.Class #if !MIN_VERSION_base(4,7,0) import Data.Proxy #endif data MySQL = MySQL MySQL.Connection deriving Typeable instance MySQL.Param a => MySQL.QueryParams (Only a) where renderParams (Only v) = MySQL.renderParams $ MySQL.Only v instance MySQL.Result a => MySQL.QueryResults (Only a) where convertResults a b = Only . MySQL.fromOnly $ MySQL.convertResults a b instance (MySQL.QueryParams a, MySQL.QueryParams b) => MySQL.QueryParams (a :. b) where renderParams (a :. b) = MySQL.renderParams a ++ MySQL.renderParams b class MySQL.QueryResults a => QueryResultsN a where queryLength :: proxy a -> Int instance MySQL.Result a => QueryResultsN (Only a) where queryLength _ = 1 instance (MySQL.Result a, MySQL.Result b) => QueryResultsN (a,b) where queryLength _ = 2 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c) => QueryResultsN (a,b,c) where queryLength _ = 3 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c, MySQL.Result d) => QueryResultsN (a,b,c,d) where queryLength _ = 4 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c, MySQL.Result d, MySQL.Result e) => QueryResultsN (a,b,c,d,e) where queryLength _ = 5 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c, MySQL.Result d, MySQL.Result e, MySQL.Result f) => QueryResultsN (a,b,c,d,e,f) where queryLength _ = 6 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c, MySQL.Result d, MySQL.Result e, MySQL.Result f, MySQL.Result g) => QueryResultsN (a,b,c,d,e,f,g) where queryLength _ = 7 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c, MySQL.Result d, MySQL.Result e, MySQL.Result f, MySQL.Result g, MySQL.Result h) => QueryResultsN (a,b,c,d,e,f,g,h) where queryLength _ = 8 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c, MySQL.Result d, MySQL.Result e, MySQL.Result f, MySQL.Result g, MySQL.Result h, MySQL.Result i) => QueryResultsN (a,b,c,d,e,f,g,h,i) where queryLength _ = 9 instance (MySQL.Result a, MySQL.Result b, MySQL.Result c, MySQL.Result d, MySQL.Result e, MySQL.Result f, MySQL.Result g, MySQL.Result h, MySQL.Result i, MySQL.Result j) => QueryResultsN (a,b,c,d,e,f,g,h,i,j) where queryLength _ = 10 instance (QueryResultsN a, QueryResultsN b) => QueryResultsN (a :. b) where queryLength _ = queryLength (Proxy :: Proxy a) + queryLength (Proxy :: Proxy b) instance (QueryResultsN a, QueryResultsN b) => MySQL.QueryResults (a :. b) where convertResults fs bs = let len = queryLength (Proxy :: Proxy a) (fa, fb) = splitAt len fs (ba, bb) = splitAt len bs in MySQL.convertResults fa ba :. MySQL.convertResults fb bb instance Backend MySQL where data ConnectInfo MySQL = ConnectInfo { connectHost :: String , connectPort :: Word16 , connectUser :: String , connectPassword :: String , connectDatabase :: String , connectOptions :: [B.Option] , connectPath :: FilePath , connectSSL :: Maybe B.SSLInfo } deriving (Eq, Read, Show) type ToRow MySQL = MySQL.QueryParams type FromRow MySQL = MySQL.QueryResults connect (ConnectInfo h p u w d o t s) = MySQL <$> MySQL.connect (MySQL.ConnectInfo h p u w d o t s) close (MySQL c) = MySQL.close c execute (MySQL c) t q = void . Sql $ MySQL.execute c (mySqlQuery t) q execute_ (MySQL c) t = void . Sql $ MySQL.execute_ c (mySqlQuery t) query (MySQL c) t q = Sql $ MySQL.query c (mySqlQuery t) q query_ (MySQL c) t = Sql $ MySQL.query_ c (mySqlQuery t) fold (MySQL c) q = MySQL.fold c (mySqlQuery q) fold_ (MySQL c) q = MySQL.fold_ c (mySqlQuery q) instance Transaction MySQL where begin c = execute_ c "start transaction" commit (MySQL c) = Sql $ B.commit c rollback (MySQL c) = Sql $ B.rollback c instance Default (ConnectInfo MySQL) where def = ConnectInfo h p u w d o t s where MySQL.ConnectInfo h p u w d o t s = MySQL.defaultConnectInfo mySqlQuery :: Query -> MySQL.Query mySqlQuery = MySQL.Query . T.encodeUtf8 . getQuery (typeOf (undefined :: MySQL)) mySQL :: Proxy '[MySQL] mySQL = Proxy