allDocs: create a lazy list off a cursor
This commit is contained in:
parent
344c6bb975
commit
0c019ad0e9
2 changed files with 21 additions and 6 deletions
|
@ -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
5
TODO
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue