2012-07-07 3 views
1

SQLite 데이터베이스에 바인딩하기 위해 http://hackage.haskell.org/package/sqlite-0.5.2.2을 사용하고 있습니다. 내부 * .db 파일에는 UTF-8 인코딩의 텍스트가 있습니다.이 텍스트 편집기와 sqlite CLI 도구에서 확인할 수 있습니다.SQLite 데이터베이스의 유니 코드 텍스트가 깨졌습니다.

데이터베이스에 연결하고 데이터를 검색 할 때 텍스트 내용이 손상되었습니다. 간단한 테스트는 다음과 같습니다.

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 

무엇이 잘못 되었을까요? 내가 Sqlite 또는 하스켈 I/O 및 인코딩과 함께 뭔가를 놓치고 있습니까?

+0

한 곳에서 파일을 서면입니다 : GHC이 작업에 대한 기본 인코딩을 선택하여 현재 로케일을 사용합니다. [hSetEncoding] (http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO.html#v:hSetEncoding)을 호출하여 이것이 문제인지 테스트 할 수 있습니다. –

+0

@DanielWagner 현재 사용중인 로케일이 en_US.UTF-8이므로 해당하지 않아야합니다. 텍스트 파일의 데이터는 UTF-8로 이중 인코딩 된 것처럼 보입니다. – jdevelop

+0

@DanielWagner 설정 바이너리 모드가 도움이되었습니다. 감사! – jdevelop

답변

1

실제로 문제는 SQLite 바인딩과 관련이 없으며 하스켈의 문자열 처리와 관련이 있습니다. 문제 해결 무엇 - 그것에 데이터를두기 전에 핸들에 hSetBinaryMode를 호출이 잘못 갈 수

writeIt content = withFile "test.txt" WriteMode (\handle -> hSetBinaryMode handle True >> mapM_ (\(c:a:t:[]) -> hPutStrLn handle c) content) 
관련 문제