I’m using http://hackage.haskell.org/package/sqlite-0.5.2.2 for binding to SQLite database. Inside *.db file there is text in UTF-8 encoding, I can assure this in text editor and sqlite CLI tool.
When connecting to database and retrieving data – the text content is broken. The simple test goes below:
import qualified Database.SQLite as SQL
import Control.Applicative ((<$>))
import System.IO
buildSkypeMessages dbh =
(go <$> (SQL.execStatement dbh "select chatname,author,timestamp,body_xml from messages order by chatname, timestamp")) >>=
writeIt
where
writeIt content = withFile "test.txt" WriteMode (\handle -> mapM_ (\(c:a:t:[]) -> hPutStrLn handle c) content)
go (Left msg) = fail msg
go (Right rows) = map f $ concat rows
where
f' (("chatname",SQL.Text chatname):
("author",SQL.Text author):
("timestamp",SQL.Int timestamp):
r) = ([chatname, author], r)
f xs = let (partEntry, (item:_)) = f' xs
in case item of
("body_xml",SQL.Text v) -> v:partEntry
("body_xml",SQL.Null) -> "":partEntry
escape (_,SQL.Text v) = v
escape (_,SQL.Null) = ""
escape (_,SQL.Int v) = show v
What may be wrong there? Am I missing something with Sqlite or with Haskell I/O and encodings?
Actually the problem was not related to SQLite bindings but to String handling in Haskell. What solved the problem – invoking hSetBinaryMode on handle before putting data on it: