1
+ {-# language OverloadedLists #-}
2
+ {-# language OverloadedStrings #-}
1
3
module Database.PostgreSQL.Protocol.Connection where
2
4
3
5
4
6
import qualified Data.ByteString as B
5
7
import Data.ByteString.Lazy (toStrict )
6
8
import Data.ByteString.Builder (Builder , toLazyByteString )
7
9
import Control.Monad
10
+ import Data.Traversable
11
+ import Data.Foldable
12
+ import Control.Applicative
8
13
import Data.Monoid
9
14
import Control.Concurrent
15
+ import Data.Binary.Get (Decoder (.. ), runGetIncremental , pushChunk )
10
16
import Data.Maybe (fromJust )
11
17
import System.Socket hiding (connect , close )
12
18
import qualified System.Socket as Socket (connect , close )
@@ -17,6 +23,7 @@ import System.Socket.Family.Unix
17
23
18
24
import Database.PostgreSQL.Protocol.Settings
19
25
import Database.PostgreSQL.Protocol.Encoders
26
+ import Database.PostgreSQL.Protocol.Decoders
20
27
import Database.PostgreSQL.Protocol.Types
21
28
22
29
@@ -31,10 +38,11 @@ connect :: ConnectionSettings -> IO Connection
31
38
connect settings = do
32
39
s <- socket
33
40
Socket. connect s address
34
- tid <- forkIO $ forever $ do
35
- r <- receive s 4096 mempty
36
- print r
37
41
sendMessage s $ encodeStartMessage $ consStartupMessage settings
42
+ r <- receive s 4096 mempty
43
+ readAuthMessage r
44
+
45
+ tid <- forkIO $ receiverThread s
38
46
pure $ Connection s tid
39
47
40
48
close :: Connection -> IO ()
@@ -52,3 +60,40 @@ sendMessage sock msg = void $ do
52
60
print smsg
53
61
send sock smsg mempty
54
62
63
+ readAuthMessage :: B. ByteString -> IO ()
64
+ readAuthMessage s =
65
+ case pushChunk (runGetIncremental decodeAuthResponse) s of
66
+ Done _ _ r -> case r of
67
+ AuthenticationOk -> putStrLn " Auth ok"
68
+ _ -> error " Invalid auth"
69
+ f -> error $ show s
70
+
71
+ receiverThread :: UnixSocket -> IO ()
72
+ receiverThread sock = forever $ do
73
+ r <- receive sock 4096 mempty
74
+ print r
75
+ go r
76
+ where
77
+ decoder = runGetIncremental decodeServerMessage
78
+ go str = case pushChunk decoder str of
79
+ Done rest _ v -> do
80
+ print v
81
+ unless (B. null rest) $ go rest
82
+ Partial _ -> error " Partial"
83
+ Fail _ _ e -> error e
84
+
85
+ sendQuery :: Connection -> IO ()
86
+ sendQuery (Connection s _) = do
87
+ sendMessage s $ encodeClientMessage $ Parse " test" " SELECT $1 + $2" [23 , 23 ]
88
+ sendMessage s $ encodeClientMessage $
89
+ Bind " test" " test" Text [" 2" , " 3" ] Text
90
+ sendMessage s $ encodeClientMessage $ Execute " test"
91
+ sendMessage s $ encodeClientMessage Sync
92
+
93
+ test :: IO ()
94
+ test = do
95
+ c <- connect defaultConnectionSettings
96
+ sendQuery c
97
+ threadDelay 3000
98
+ close c
99
+
0 commit comments