allDocs: create a lazy list off a cursor

This commit is contained in:
Scott R. Parish 2010-01-16 19:14:47 -06:00
parent 344c6bb975
commit 0c019ad0e9
2 changed files with 21 additions and 6 deletions

View file

@ -2,8 +2,8 @@ module Database.MongoDB
( (
connect, connectOnPort, conClose, connect, connectOnPort, conClose,
delete, insert, insertMany, query, remove, update, delete, insert, insertMany, query, remove, update,
nextDoc, finish,
find, find,
allDocs, finish, nextDoc,
Collection, FieldSelector, NumToSkip, NumToReturn, RequestID, Selector, Collection, FieldSelector, NumToSkip, NumToReturn, RequestID, Selector,
Opcode(..), Opcode(..),
QueryOpt(..), QueryOpt(..),
@ -28,6 +28,7 @@ import qualified Network
import Network.Socket hiding (connect, send, sendTo, recv, recvFrom) import Network.Socket hiding (connect, send, sendTo, recv, recvFrom)
import Prelude hiding (getContents) import Prelude hiding (getContents)
import System.IO import System.IO
import System.IO.Unsafe
import System.Random import System.Random
data Connection = Connection { cHandle :: Handle, cRand :: IORef [Int] } data Connection = Connection { cHandle :: Handle, cRand :: IORef [Int] }
@ -253,6 +254,25 @@ nextDoc cur = do
writeIORef (curDocBytes cur) docBytes' writeIORef (curDocBytes cur) docBytes'
return $ Just doc return $ Just doc
{- | Return a lazy list of all (of the rest) of the documents in the
cursor. This works much like hGetContents--it will lazily read the
cursor data out of the database as the list is used. The cursor is
automatically closed when the list has been fully read.
If you manually finish the cursor before consuming off this list you
won't get all the original documents in the cursor.
If you don't consume to the end of the list, you must manually close
the cursor or you will leak the cursor, which may also leak on the
database side.
-}
allDocs :: Cursor -> IO [BSONObject]
allDocs cur = unsafeInterleaveIO $ do
doc <- nextDoc cur
case doc of
Nothing -> return []
Just d -> allDocs cur >>= return . (d :)
getFirstDoc docBytes = flip runGet docBytes $ do getFirstDoc docBytes = flip runGet docBytes $ do
doc <- get doc <- get
docBytes' <- getRemainingLazyByteString docBytes' <- getRemainingLazyByteString

5
TODO
View file

@ -12,11 +12,6 @@ MongoDB
------- -------
+ support safe operations + support safe operations
+ auto-reconnection + auto-reconnection
+ seemless iterator (using lazy lists?) (unsafeInterleaveIO)
- hdbc has a fetchRow that returns a Maybe and auto-closes their statement
once everything's been read
- hdbc has a fetchAllRows that builds up a lazy list using fetchRow (so
it auto-closes the statement)
+ destoy cursor (how?/when?) + destoy cursor (how?/when?)
Misc Misc