diff --git a/hascas.cabal b/hascas.cabal
--- a/hascas.cabal
+++ b/hascas.cabal
@@ -1,7 +1,7 @@
 name:                hascas
-version:             0.1.0.0
+version:             1.0.0
 synopsis:            Cassandra driver for haskell
-description:         Please see README.md
+description:         This is a cassandra driver.
 homepage:            https://github.com/eklavya/hascas#readme
 license:             Apache
 license-file:        LICENSE
@@ -32,6 +32,7 @@
                      , stm
                      , data-binary-ieee754
                      , mtl
+                     , safe-exceptions
                      , template-haskell
   default-language:    Haskell2010
 
@@ -50,6 +51,7 @@
                      , data-binary-ieee754
                      , hspec
                      , mtl
+                     , safe-exceptions
                      , template-haskell
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
   default-language:    Haskell2010
diff --git a/src/Batch.hs b/src/Batch.hs
--- a/src/Batch.hs
+++ b/src/Batch.hs
@@ -41,6 +41,7 @@
 
 
 instance Batchable LoggedBatch where
+  -- | Execute your batch query
   runBatch (LoggedBatch qs) = do
     (Candle driverQ)  <- ask
     mvar <- liftIO newEmptyMVar
@@ -48,7 +49,7 @@
     liftIO $ atomically $ writeTBQueue driverQ (LongStr q, 13, mvar)
     res <- liftIO $ takeMVar mvar
     case res of
-      Left e -> throwError e
+      Left e             -> throwError e
       Right (RRows rows) -> return rows
 
 
diff --git a/src/CQL.hs b/src/CQL.hs
--- a/src/CQL.hs
+++ b/src/CQL.hs
@@ -1,9 +1,162 @@
-module CQL (module X) where
+{- |
+Module      : CQL
+Description : Cassandra Driver
+Copyright   : (c) Saurabh Rawat, 2016
+License     : Apache
+Maintainer  : saurabh.rawat90@gmail.com
 
-import           Batch    as X
-import           Codec    as X
-import           Common   as X
-import           Derive   as X
-import           Driver   as X
-import           Encoding as X
-import           Query    as X
+This is a cassandra driver. It currently has:
+
+- Select
+- Insert
+- Update
+- Delete
+- Prepared Queries
+- Batch Queries
+- Automatic Records Conversion
+- Collections
+
+The driver gets the list of all nodes in the cluster and load balances amongst them. So you can connect to any one node in the cluster and it will
+take care of the rest.
+
+Initialize the driver by calling
+
+@
+  CQL.init host port
+@
+
+for example
+
+@
+  CQL.init "127.0.0.1" (PortNumber 9042)
+@
+
+Example:
+
+@
+data Emp = Emp {
+  empID    :: Int64,
+  deptID   :: Int32,
+  alive    :: Bool ,
+  id       :: UUID,
+  name     :: CQLString,
+  salary   :: CQLDouble,
+  someList :: CQLList Int32,
+  someSet  :: CQLSet CQLDouble,
+  someMap  :: CQLMap CQLString CQLString
+}
+  deriving(Show, Eq)
+
+deriveBuildRec ''Emp
+
+main :: IO ()
+main = do
+    candle <- CQL.init "127.0.0.1" (PortNumber 9042)
+
+    res <- flip runReaderT candle $ runExceptT $ do
+      let q = create "keyspace demodb WITH REPLICATION = {'class' : 'SimpleStrategy','replication_factor': 1}"
+      runCQL LOCAL_ONE q
+
+      --create a table
+      let tableQuery = "TABLE demodb.emp (empID bigint,deptID int,alive boolean,id uuid,name varchar,salary double,"
+                       ++ "someset set<double>,somelist list<int>,somemap map<text, text>,PRIMARY KEY (empID, deptID))"
+
+      let q = create tableQuery
+      runCQL LOCAL_ONE q
+
+      --execute prepared queries
+      p <- prepare "INSERT INTO demodb.emp (empID,deptID,alive,id,name,salary,somelist,someset,somemap) VALUES (?,?,?,?,?,?,?,?,?)"
+      execCQL LOCAL_ONE p [
+            put (104::Int64),
+            put (15::Int32),
+            put True,
+            put $ fromJust $ fromString "38d0ceb1-9e3e-427c-bc36-0106398f672b",
+            put $ CQLString "Hot Shot",
+            put $ CQLDouble 100000.0,
+            put ((CQLList [1,2,3,4,5,6]) :: CQLList Int32),
+            put ((CQLSet $ fromList [CQLDouble 0.001, CQLDouble 1000.0]) :: CQLSet CQLDouble),
+            put $ CQLMap $ DMS.fromList [(CQLString "some", CQLString "Things")]]
+
+      -- execute prepared queries and get results
+      p <- prepare "select empID, deptID, alive, id, name, salary, someset, somemap, somelist from demodb.emp where empid = ? and deptid = ?"
+      res <- execCQL LOCAL_ONE p [
+            put (104::Int64),
+            put (15::Int32)]
+      liftIO $ print $ catMaybes ((fmap fromRow res)::[Maybe Emp])
+      liftIO $ print (fromCQL (Prelude.head res) (CQLString "salary")::Maybe Double)
+      liftIO $ print (fromCQL (Prelude.head res) (CQLString "name")::Maybe CQLString)
+
+      --select rows from table
+      let q = select "demodb.emp" # where' "empID" (104::Int64) # and' "deptID" (15::Int32)
+      rows <- runCQL LOCAL_ONE q
+      liftIO $ print $ catMaybes ((fmap fromRow res)::[Maybe Emp])
+
+      --batch queries
+      p <- prepare "INSERT INTO demodb.emp (empID, deptID, alive, id, name, salary) VALUES (?, ?, ?, ?, ?, ?)"
+      let q = batch (update "demodb.emp" # with "name" (CQLString "some name") # where' "empID" (104::Int64) # and' "deptID" (15::Int32)) <>
+            batch (update "demodb.emp" # with "alive" False # where' "empID" (104::Int64) # and' "deptID" (15::Int32)) <>
+            prepBatch p [
+                        put (101::Int64),
+                        put (13::Int32),
+                        put True,
+                        put $ fromJust $ fromString "48d0ceb1-9e3e-427c-bc36-0106398f672b",
+                        put $ CQLString "Hot1 Shot1",
+                        put $ CQLDouble 10000.0]
+      runBatch q
+
+      --drop a table
+      let q = drop' "table demodb.emp"
+      runCQL LOCAL_ONE q
+
+      --drop a keyspace
+      let q = drop' "keyspace demodb"
+      runCQL LOCAL_ONE q
+
+    print res
+
+@
+
+-}
+
+module CQL (
+           Driver.init,
+           Consistency(..),
+           -- ** Data Types
+           Rows,
+           Row,
+           Bytes(..),
+           CQLDouble(..),
+           CQLString(..),
+           CQLMap(..),
+           CQLSet(..),
+           CQLList(..),
+           -- ** Auto derive conversion for record types
+           deriveBuildRec,
+           fromRow,
+           -- ** DSL for creating queries
+           (#),
+           create,
+           drop',
+           select,
+           limit,
+           update,
+           with,
+           delete,
+           where',
+           and',
+           -- ** Prepare and run queries
+           runCQL,
+           prepare,
+           execCQL,
+           -- ** Batching
+           batch,
+           prepBatch,
+           runBatch) where
+
+import           Batch
+import           Codec
+import           Common
+import           Derive
+import           Driver
+import           Encoding
+import           Query
diff --git a/src/Common.hs b/src/Common.hs
--- a/src/Common.hs
+++ b/src/Common.hs
@@ -74,7 +74,7 @@
   deriving(Eq, Ord, Show)
 
 newtype LongStr = LongStr DBL.ByteString
-  deriving(Show)
+  deriving(Show, Eq, Ord)
 
 newtype Bytes = Bytes DBL.ByteString
   deriving(Show, Eq, Ord)
@@ -151,6 +151,7 @@
 
 -- | Auto derivable class to get records from result rows.
 class BuildRec a where
+  -- | Get the result from a row.
   fromRow :: Row -> Maybe a
 
 -- | All field types must implement this class.
diff --git a/src/Derive.hs b/src/Derive.hs
--- a/src/Derive.hs
+++ b/src/Derive.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE QuasiQuotes       #-}
@@ -36,7 +37,11 @@
 
 -- | Derives BuildRec instances for record types.
 deriveBuildRec a = do
+#if __GLASGOW_HASKELL__ >= 800
+  TyConI (DataD _ cName _ _ constructors _) <- reify a
+#else
   TyConI (DataD _ cName _ constructors _) <- reify a
+#endif
   case head constructors of
     (RecC conName args) -> do
       names <- genNames $ length args
diff --git a/src/Driver.hs b/src/Driver.hs
--- a/src/Driver.hs
+++ b/src/Driver.hs
@@ -4,16 +4,19 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 
 
-module Driver (Driver.init) where
+module Driver (Driver.init, Driver.allConnections) where
 
 
+import           Codec
+import           Common
 import           Control.Applicative
 import           Control.Concurrent
 import           Control.Concurrent.MVar
 import           Control.Concurrent.STM
 import           Control.Concurrent.STM.TBQueue
-import           Control.Exception              (bracket, catch)
+import           Control.Exception              (bracket, catch, mask)
 import           Control.Monad                  (forM_, forever, replicateM)
+import           Control.Monad.Except
 import           Data.Binary
 import           Data.Binary.Get
 import           Data.Binary.IEEE754
@@ -22,21 +25,21 @@
 import           Data.ByteString
 import qualified Data.ByteString.Char8          as C8
 import qualified Data.ByteString.Lazy           as DBL
+import           Data.Either
 import           Data.Int
 import qualified Data.IntMap                    as IM
 import           Data.List
 import qualified Data.Map.Strict                as DMS
-
-import           Codec
-import           Common
 import           Data.Maybe
 import           Data.Monoid                    as DM
+import           Data.Set
 import           Data.UUID
 import           Debug.Trace
 import           Encoding
 import           GHC.Generics                   (Generic)
 import           GHC.IO.Handle                  (Handle, hClose, hFlush)
 import           Network
+import           System.IO.Unsafe
 
 
 startUp :: Handle -> IO ()
@@ -50,18 +53,37 @@
   return ()
 
 
+registerForEvents :: Handle -> IO ()
+registerForEvents h = do
+  let s = encode $ CQLList [CQLString "TOPOLOGY_CHANGE", CQLString "STATUS_CHANGE"]
+  let register = DBL.toStrict $ DBL.pack [4, 0, 0, 1, 11] <> encode (fromIntegral (DBL.length s)::Int32) <> s
+  hPut h register
+  header <- hGet h 9
+  he <- pure $ runGet (get :: Get Header) $ DBL.fromStrict header
+  hGet h (fromIntegral $ len he)
+  return ()
+
+
+{-# NOINLINE prepareQueries #-}
+prepareQueries :: MVar (Set LongStr)
+prepareQueries = unsafePerformIO $ do
+  mvar <- newEmptyMVar
+  putMVar mvar Data.Set.empty
+  return mvar
+
+
 receiveThread :: Handle -> MVar [Int16] -> MVar(IM.IntMap (MVar (Either ShortStr Result))) -> IO ()
 receiveThread h streams streamMap = do
   forkIO $ forever $ do
         header <- hGet h 9
         he <- pure $ runGet (get :: Get Header) $ DBL.fromStrict header
         p <- hGet h (fromIntegral $ len he)
-        if opcode he == 0
-          then do
+        case opcode he of
+          0 -> do
             let (erCode, erMsg) = runGet getErr (DBL.fromStrict p)
             mvar <- getResHolder he streams streamMap
             putMVar mvar (Left erMsg)
-          else do
+          8 -> do
             let resultType = runGet (get :: Get Int32) (DBL.fromStrict p)
 
             case resultType of
@@ -82,6 +104,9 @@
               5 -> do
                 mvar <- getResHolder he streams streamMap
                 putMVar mvar (Right $ RRows [])
+          -- 12 -> do
+          --   print "something happened"
+          --   print $ runGet (get :: Get ShortStr) (DBL.fromStrict p)
   return ()
 
 
@@ -97,35 +122,104 @@
           return mvar
 
 
+someDef :: Handle -> MVar [Int16] -> MVar (IM.IntMap (MVar (Either ShortStr Result))) -> (LongStr, Word8, MVar (Either ShortStr Result)) -> IO ()
+someDef h streams streamMap (bs, opc, mvar) = do
+      strs <- takeMVar streams
+      case Data.List.uncons strs of
+        Just (i, strsTail) -> do
+          putMVar streams strsTail
+          m <- takeMVar streamMap
+          let m' = IM.insert (fromIntegral i :: Int) mvar m
+          putMVar streamMap m'
+          seq m' (return ())
+          let bs' = Data.ByteString.pack [4, 0] <> DBL.toStrict (encode i <> DBL.pack [opc] <> encode bs)
+          hPut h bs'
+
+        Nothing -> do
+          putMVar streams strs
+          someDef h streams streamMap (bs, opc, mvar)
+
+
 sendThread :: Handle -> MVar [Int16] -> MVar(IM.IntMap (MVar (Either ShortStr Result))) -> TBQueue (LongStr, Word8, MVar (Either ShortStr Result)) -> IO ()
 sendThread h streams streamMap driverQ = do
   forkIO $ forever $ do
-          strs <- takeMVar streams
-          case Data.List.uncons strs of
-            Just (i, strsTail) -> do
-              putMVar streams strsTail
-              (bs, opc, mvar) <- atomically $ readTBQueue driverQ
-              m <- takeMVar streamMap
-              let m' = IM.insert (fromIntegral i :: Int) mvar m
-              putMVar streamMap m'
-              seq m' (return ())
-              let bs' = Data.ByteString.pack [4, 0] <> DBL.toStrict (encode i <> DBL.pack [opc] <> encode bs)
-              hPut h bs'
-            Nothing -> do
-              putMVar streams strs
-              sendThread h streams streamMap driverQ
+          (bs, opc, mvar) <- atomically $ readTBQueue driverQ
+          when (opc == 9) $ do
+             pq <- takeMVar prepareQueries
+             putMVar prepareQueries (Data.Set.insert bs pq)
+             cons <- readMVar allConnections
+             mvars <- forM cons $ \(_, h', str, strMap) -> do
+               mv <- newEmptyMVar
+               someDef h' str strMap (bs, opc, mv)
+               return mv
+             forkIO $ do
+               ls <- sequence $ fmap (\mva -> do {a <- takeMVar mva; return a}) mvars
+               putMVar mvar $ Data.List.foldl' (\b a -> if isLeft a then a else b) (Data.List.head ls) (Data.List.tail ls)
+             return ()
+          when (opc /= 9) $ someDef h streams streamMap (bs, opc, mvar)
   return ()
 
--- | The first 
-init :: HostName -> PortID -> IO Candle
+
+getPeers :: Handle -> IO (Either ShortStr [Row])
+getPeers h = do
+  let q' = "select peer from system.peers"
+  let q = q' <> encode LOCAL_ONE <> encode (0x00 :: Int8)
+  let l = fromIntegral (DBL.length q')::Int32
+  let hd = LongStr $ encode l <> q
+  let bs' = Data.ByteString.pack [4, 0] <> DBL.toStrict (encode (0::Int16) <> DBL.pack [7] <> encode hd)
+  hPut h bs'
+  header <- hGet h 9
+  he <- pure $ runGet (get :: Get Header) $ DBL.fromStrict header
+  p <- hGet h (fromIntegral $ len he)
+  if opcode he == 0
+    then do
+      let (erCode, erMsg) = runGet getErr (DBL.fromStrict p)
+      return $ Left erMsg
+    else do
+      let resultType = runGet (get :: Get Int32) (DBL.fromStrict p)
+      case resultType of
+        2 -> do
+          let rows = content $ runGet getRows (DBL.fromStrict $ C8.drop 4 p)
+          return $ Right rows
+        _ ->
+          return $ Left $ ShortStr "Could not get list of peers. Please check if this cassandra version is supported."
+
+
+{-# NOINLINE allConnections #-}
+allConnections :: MVar [(HostName, Handle, MVar [Int16], MVar(IM.IntMap (MVar (Either ShortStr Result))))]
+allConnections = unsafePerformIO $ newMVar []
+
+
+-- | The first function you need to call. It initializes the driver and connects to the cluster.
+-- You only need to specify one node from your cluster here.
+init :: HostName -> PortID -> ExceptT ShortStr IO Candle
 init host port = do
-    streamNum <- newMVar 0
-    streams <- newMVar ([0..32767] :: [Int16])
-    streamMap <- newMVar (IM.empty :: (IM.IntMap (MVar (Either ShortStr Result))))
-    driverQ <- atomically $ newTBQueue 32768
+    streamNum <- liftIO $ newMVar 0
+    streams <- liftIO $ newMVar ([0..32767] :: [Int16])
+    streamMap <- liftIO $ newMVar (IM.empty :: (IM.IntMap (MVar (Either ShortStr Result))))
+    driverQ <- liftIO $ atomically $ newTBQueue 32768
 
-    h <- connectTo host port
-    startUp h
-    receiveThread h streams streamMap
-    sendThread h streams streamMap driverQ
-    return $ Candle driverQ
+    h <- liftIO $ connectTo host port
+    liftIO $ startUp h
+    -- liftIO $ registerForEvents h
+
+    res <- liftIO $ getPeers h
+    case res of
+      Left err -> throwError err
+      Right rows -> do
+        let peers = (\(CQLString p) -> Data.List.concat <$> Data.List.intersperse "." $ fmap show (unpack p)) <$> catMaybes (fmap (\r -> fromCQL r (CQLString "peer")::Maybe CQLString) rows)
+        oCons <- liftIO $ sequence $ fmap (\peer -> do
+                        streams <- newMVar ([0..32767] :: [Int16])
+                        streamMap <- newMVar (IM.empty :: (IM.IntMap (MVar (Either ShortStr Result))))
+                        h <- connectTo peer port
+                        startUp h
+                        -- registerForEvents h
+                        return (peer, h, streams, streamMap)
+                    ) peers
+        let connections = (host, h, streams, streamMap) : oCons
+        allCon <- liftIO $ takeMVar allConnections
+        liftIO $ putMVar allConnections connections
+        forM_ connections (\(_, h, streams, streamMap) -> do
+          liftIO $ receiveThread h streams streamMap
+          liftIO $ sendThread h streams streamMap driverQ)
+        return $ Candle driverQ
diff --git a/src/Query.hs b/src/Query.hs
--- a/src/Query.hs
+++ b/src/Query.hs
@@ -68,6 +68,7 @@
 and' n v = Query (ShortStr (" and " <> DBL.fromStrict (C8.pack n) <> " = ? ")) [(DBL.toStrict . addLength . runPut . put) v]
 
 
+-- | Prepare a query, returns a prepared query which can be fed to execCQL for execution.
 prepare :: ByteString -> ExceptT ShortStr (ReaderT Candle IO) Prepared
 prepare q = do
   (Candle driverQ) <- ask
@@ -77,10 +78,11 @@
   liftIO $ atomically $ writeTBQueue driverQ (LongStr hd, 9, mvar)
   res <- liftIO $ takeMVar mvar
   case res of
-    Left e -> throwError e
-    Right (RPrepared sb) -> return $ Prepared sb
+      Left e -> throwError e
+      Right (RPrepared sb) -> return $ Prepared sb
 
 
+-- | Run a query directly.
 runCQL :: Consistency -> Q -> ExceptT ShortStr (ReaderT Candle IO) [Row]
 runCQL c (Query (ShortStr q) bs) = do
   (Candle driverQ) <- ask
@@ -96,6 +98,7 @@
     Right (RRows rows) -> return rows
 
 
+-- | Execute a prepared query.
 execCQL :: Consistency -> Prepared -> [Put] -> ExceptT ShortStr (ReaderT Candle IO) [Row]
 execCQL c (Prepared pid) ls = do
   (Candle driverQ) <- ask
@@ -109,6 +112,10 @@
     Right (RRows rows) -> return rows
 
 
+-- | Combine DSL actions
+-- @
+--  select "demodb.emp" # where' "empID" (104::Int64) # and' "deptID" (15::Int32)
+-- @
 (#) :: Q -> Q -> Q
 (#) (Query s1 bs1) (Query s2 bs2) = Query (s1 <> s2) (bs1 <> bs2)
 
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -60,80 +60,85 @@
 
 main :: IO ()
 main = do
-    ch <- CQL.init "127.0.0.1" (PortNumber 9042)
+    conRes <- runExceptT $ CQL.init "127.0.0.1" (PortNumber 9042)
+    case conRes of
+      Right ch ->
+        hspec $ before (threadDelay 1000000) (describe "driver should be able to" $ do
+            it "create a keyspace" $ do
+               let q = create "keyspace demodb WITH REPLICATION = {'class' : 'SimpleStrategy','replication_factor': 2}"
+               res <- (runReaderT . runExceptT) (runCQL ALL q) ch
+               res `shouldBe` Right []
 
-    hspec $
-      describe "driver should be able to" $ do
-        it "create a keyspace" $ do
-          let q = create "keyspace demodb WITH REPLICATION = {'class' : 'SimpleStrategy','replication_factor': 1}"
-          res <- (runReaderT . runExceptT) (runCQL LOCAL_ONE q) ch
-          res `shouldBe` Right []
 
-        it "create a table" $ do
-          let tableQuery = "TABLE demodb.emp (empID bigint,deptID int,alive boolean,id uuid,name varchar,salary double,"
-                       ++ "someset set<double>,somelist list<int>,somemap map<text, text>,PRIMARY KEY (empID, deptID))"
-          let q = create tableQuery
-          res <- (runReaderT . runExceptT) (runCQL LOCAL_ONE q) ch
-          res `shouldBe` Right []
+            it "create a table" $ do
+               let tableQuery = "TABLE demodb.emp (empID bigint,deptID int,alive boolean,id uuid,name varchar,salary double,"
+                                ++ "someset set<double>,somelist list<int>,somemap map<text, text>,PRIMARY KEY (empID, deptID))"
+               let q = create tableQuery
+               res <- (runReaderT . runExceptT) (runCQL ALL q) ch
+               res `shouldBe` Right []
 
-        it "execute prepared queries" $ do
-          prep <- (runReaderT . runExceptT) (prepare "INSERT INTO demodb.emp (empID,deptID,alive,id,name,salary,somelist,someset,somemap) VALUES (?,?,?,?,?,?,?,?,?)") ch
-          case prep of
-            Left e -> print e
-            Right p -> do
-              res <- (runReaderT . runExceptT) (execCQL LOCAL_ONE p [
-                put (104::Int64),
-                put (15::Int32),
-                put True,
-                put $ fromJust $ fromString "38d0ceb1-9e3e-427c-bc36-0106398f672b",
-                put $ CQLString "Hot Shot",
-                put $ CQLDouble 100000.0,
-                put ((CQLList [1,2,3,4,5,6]) :: CQLList Int32),
-                put ((CQLSet $ fromList [CQLDouble 0.001, CQLDouble 1000.0]) :: CQLSet CQLDouble),
-                put $ CQLMap $ DMS.fromList [(CQLString "some", CQLString "Things")]]) ch
-              res `shouldBe` Right []
 
-        it "execute prepared queries and get results" $ do
-          prep <- (runReaderT . runExceptT) (prepare "select empID, deptID, alive, id, name, salary, someset, somemap, somelist from demodb.emp where empid = ? and deptid = ?") ch
-          case prep of
-            Left e -> print e
-            Right p -> do
-              res <- (runReaderT . runExceptT) (execCQL LOCAL_ONE p [
-                put (104::Int64),
-                put (15::Int32)]) ch
+            it "execute prepared queries" $ do
+              prep <- (runReaderT . runExceptT) (prepare "INSERT INTO demodb.emp (empID,deptID,alive,id,name,salary,somelist,someset,somemap) VALUES (?,?,?,?,?,?,?,?,?)") ch
+              case prep of
+                Left e -> print e
+                Right p -> do
+                  res <- (runReaderT . runExceptT) (execCQL QUORUM p [
+                    put (104::Int64),
+                    put (15::Int32),
+                    put True,
+                    put $ fromJust $ fromString "38d0ceb1-9e3e-427c-bc36-0106398f672b",
+                    put $ CQLString "Hot Shot",
+                    put $ CQLDouble 100000.0,
+                    put ((CQLList [1,2,3,4,5,6]) :: CQLList Int32),
+                    put ((CQLSet $ fromList [CQLDouble 0.001, CQLDouble 1000.0]) :: CQLSet CQLDouble),
+                    put $ CQLMap $ DMS.fromList [(CQLString "some", CQLString "Things")]]) ch
+                  res `shouldBe` Right []
+
+            it "execute prepared queries and get results" $ do
+              prep <- (runReaderT . runExceptT) (prepare "select empID, deptID, alive, id, name, salary, someset, somemap, somelist from demodb.emp where empid = ? and deptid = ?") ch
+              case prep of
+                Left e -> print e
+                Right p -> do
+                  res <- (runReaderT . runExceptT) (execCQL QUORUM p [
+                    put (104::Int64),
+                    put (15::Int32)]) ch
+                  fmap fromRow <$> res `shouldBe` Right [Just (Emp {empID = 104, deptID = 15, alive = True, Main.id = fromJust $ fromString $ "38d0ceb1-9e3e-427c-bc36-0106398f672b", name = CQLString "Hot Shot", salary = CQLDouble 100000.0, someList = CQLList [1,2,3,4,5,6], someSet = CQLSet (fromList [CQLDouble 1.0e-3,CQLDouble 1000.0]), someMap = CQLMap $ DMS.fromList [(CQLString "some",CQLString "Things")]})]
+
+            it "select rows from table" $ do
+              let q = select "demodb.emp" # where' "empID" (104::Int64) # and' "deptID" (15::Int32)
+              res <- (runReaderT . runExceptT) (runCQL QUORUM q) ch
               fmap fromRow <$> res `shouldBe` Right [Just (Emp {empID = 104, deptID = 15, alive = True, Main.id = fromJust $ fromString $ "38d0ceb1-9e3e-427c-bc36-0106398f672b", name = CQLString "Hot Shot", salary = CQLDouble 100000.0, someList = CQLList [1,2,3,4,5,6], someSet = CQLSet (fromList [CQLDouble 1.0e-3,CQLDouble 1000.0]), someMap = CQLMap $ DMS.fromList [(CQLString "some",CQLString "Things")]})]
 
-        it "select rows from table" $ do
-          let q = select "demodb.emp" # where' "empID" (104::Int64) # and' "deptID" (15::Int32)
-          res <- (runReaderT . runExceptT) (runCQL LOCAL_ONE q) ch
-          fmap fromRow <$> res `shouldBe` Right [Just (Emp {empID = 104, deptID = 15, alive = True, Main.id = fromJust $ fromString $ "38d0ceb1-9e3e-427c-bc36-0106398f672b", name = CQLString "Hot Shot", salary = CQLDouble 100000.0, someList = CQLList [1,2,3,4,5,6], someSet = CQLSet (fromList [CQLDouble 1.0e-3,CQLDouble 1000.0]), someMap = CQLMap $ DMS.fromList [(CQLString "some",CQLString "Things")]})]
+            it "batch queries" $ do
+              prep <- (runReaderT . runExceptT) (prepare "INSERT INTO demodb.emp (empID, deptID, alive, id, name, salary) VALUES (?, ?, ?, ?, ?, ?)") ch
+              case prep of
+                Left e -> print e
+                Right p -> do
+                  let q = batch (update "demodb.emp" # with "name" (CQLString "some name") # where' "empID" (104::Int64) # and' "deptID" (15::Int32)) <>
+                          batch (update "demodb.emp" # with "alive" False # where' "empID" (104::Int64) # and' "deptID" (15::Int32)) <>
+                          prepBatch p [
+                            put (101::Int64),
+                            put (13::Int32),
+                            put True,
+                            put $ fromJust $ fromString "48d0ceb1-9e3e-427c-bc36-0106398f672b",
+                            put $ CQLString "Hot1 Shot1",
+                            put $ CQLDouble 10000.0]
+                  res <- (runReaderT . runExceptT) (runBatch q) ch
+                  res `shouldBe` Right []
+                  let q = select "demodb.emp" # where' "empID" (101::Int64) # and' "deptID" (13::Int32)
+                  res <- (runReaderT . runExceptT) (runCQL QUORUM q) ch
+                  fmap fromRow <$> res `shouldBe` Right [Just (Emp {empID = 101, deptID = 13, alive = True, Main.id = fromJust $ fromString $ "48d0ceb1-9e3e-427c-bc36-0106398f672b", name = CQLString "Hot1 Shot1", salary = CQLDouble 10000.0, someList = CQLList [], someSet = CQLSet Data.Set.empty, someMap = CQLMap DMS.empty})]
 
-        it "batch queries" $ do
-          prep <- (runReaderT . runExceptT) (prepare "INSERT INTO demodb.emp (empID, deptID, alive, id, name, salary) VALUES (?, ?, ?, ?, ?, ?)") ch
-          case prep of
-            Left e -> print e
-            Right p -> do
-              let q = batch (update "demodb.emp" # with "name" (CQLString "some name") # where' "empID" (104::Int64) # and' "deptID" (15::Int32)) <>
-                      batch (update "demodb.emp" # with "alive" False # where' "empID" (104::Int64) # and' "deptID" (15::Int32)) <>
-                      prepBatch p [
-                        put (101::Int64),
-                        put (13::Int32),
-                        put True,
-                        put $ fromJust $ fromString "48d0ceb1-9e3e-427c-bc36-0106398f672b",
-                        put $ CQLString "Hot1 Shot1",
-                        put $ CQLDouble 10000.0]
-              res <- (runReaderT . runExceptT) (runBatch q) ch
+            it "drop a table" $ do
+              let q = drop' "table demodb.emp"
+              res <- (runReaderT . runExceptT) (runCQL ALL q) ch
               res `shouldBe` Right []
-              let q = select "demodb.emp" # where' "empID" (101::Int64) # and' "deptID" (13::Int32)
-              res <- (runReaderT . runExceptT) (runCQL LOCAL_ONE q) ch
-              fmap fromRow <$> res `shouldBe` Right [Just (Emp {empID = 101, deptID = 13, alive = True, Main.id = fromJust $ fromString $ "48d0ceb1-9e3e-427c-bc36-0106398f672b", name = CQLString "Hot1 Shot1", salary = CQLDouble 10000.0, someList = CQLList [], someSet = CQLSet Data.Set.empty, someMap = CQLMap DMS.empty})]
 
-        it "drop a table" $ do
-          let q = drop' "table demodb.emp"
-          res <- (runReaderT . runExceptT) (runCQL LOCAL_ONE q) ch
-          res `shouldBe` Right []
+            it "drop a keyspace" $ do
+              let q = drop' "keyspace demodb"
+              res <- (runReaderT . runExceptT) (runCQL ALL q) ch
+              res `shouldBe` Right [])
 
-        it "drop a keyspace" $ do
-          let q = drop' "keyspace demodb"
-          res <- (runReaderT . runExceptT) (runCQL LOCAL_ONE q) ch
-          res `shouldBe` Right []
+      Left err ->
+        print err
