packages feed

cassandra-cql 0.2.0.1 → 0.2.0.2

raw patch · 2 files changed

+91/−72 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Database.Cassandra.CQL: AlreadyExists :: Text -> Keyspace -> Table -> CassandraException
+ Database.Cassandra.CQL: AlreadyExists :: Text -> Keyspace -> Table -> Text -> CassandraException
- Database.Cassandra.CQL: AuthenticationException :: Text -> CassandraException
+ Database.Cassandra.CQL: AuthenticationException :: Text -> CassandraCommsError
- Database.Cassandra.CQL: BadCredentials :: Text -> CassandraException
+ Database.Cassandra.CQL: BadCredentials :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: ConfigError :: Text -> CassandraException
+ Database.Cassandra.CQL: ConfigError :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: Invalid :: Text -> CassandraException
+ Database.Cassandra.CQL: Invalid :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: IsBootstrapping :: Text -> CassandraException
+ Database.Cassandra.CQL: IsBootstrapping :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: LocalProtocolError :: Text -> CassandraCommsError
+ Database.Cassandra.CQL: LocalProtocolError :: Text -> Text -> CassandraCommsError
- Database.Cassandra.CQL: Overloaded :: Text -> CassandraException
+ Database.Cassandra.CQL: Overloaded :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: ProtocolError :: Text -> CassandraException
+ Database.Cassandra.CQL: ProtocolError :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: ReadTimeout :: Text -> Consistency -> Int -> Int -> Bool -> CassandraException
+ Database.Cassandra.CQL: ReadTimeout :: Text -> Consistency -> Int -> Int -> Bool -> Text -> CassandraException
- Database.Cassandra.CQL: ServerError :: Text -> CassandraException
+ Database.Cassandra.CQL: ServerError :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: SyntaxError :: Text -> CassandraException
+ Database.Cassandra.CQL: SyntaxError :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: TruncateError :: Text -> CassandraException
+ Database.Cassandra.CQL: TruncateError :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: Unauthorized :: Text -> CassandraException
+ Database.Cassandra.CQL: Unauthorized :: Text -> Text -> CassandraException
- Database.Cassandra.CQL: UnavailableException :: Text -> Consistency -> Int -> Int -> CassandraException
+ Database.Cassandra.CQL: UnavailableException :: Text -> Consistency -> Int -> Int -> Text -> CassandraException
- Database.Cassandra.CQL: Unprepared :: Text -> PreparedQueryID -> CassandraException
+ Database.Cassandra.CQL: Unprepared :: Text -> PreparedQueryID -> Text -> CassandraException
- Database.Cassandra.CQL: ValueMarshallingException :: TransportDirection -> Text -> CassandraCommsError
+ Database.Cassandra.CQL: ValueMarshallingException :: TransportDirection -> Text -> Text -> CassandraCommsError
- Database.Cassandra.CQL: WriteTimeout :: Text -> Consistency -> Int -> Int -> Text -> CassandraException
+ Database.Cassandra.CQL: WriteTimeout :: Text -> Consistency -> Int -> Int -> Text -> Text -> CassandraException

Files

Database/Cassandra/CQL.hs view
@@ -79,12 +79,21 @@ -- 'executeRows' or 'executeRow' respectively. -- -- The following pattern seems to work very well, especially along with your own 'CasType'--- instances, because it neatly hides the mechanics from the body of your code:+-- instances, because it gives you a place to neatly add marshalling details that keeps+-- away from the body of your code. -- -- > insertSong :: UUID -> Text -> Text -> Maybe Text -> Cas () -- > insertSong id title artist comment = executeWrite QUORUM q (id, title, artist, comment) -- >      where q = "insert into songs (id, title, artist, comment) values (?, ?, ?, ?)" --+-- Incidentally, here's Haskell's little-known multi-line string syntax.+-- You escape it using \\ and then another \\ where the string starts again.+--+-- > str = "multi\+-- >        \line"+--+-- (gives \"multiline\")+-- -- /To do/ -- -- * Add credentials.@@ -332,16 +341,16 @@ protocolVersion :: Word8 protocolVersion = 1 -recvFrame :: StateT ActiveSession IO (Frame ByteString)-recvFrame = do+recvFrame :: Text -> StateT ActiveSession IO (Frame ByteString)+recvFrame qt = do     s <- gets actSocket     hdrBs <- liftIO $ recvAll s 8     case runGet parseHeader hdrBs of-        Left err -> throw $ LocalProtocolError $ "recvFrame: " `T.append` T.pack err+        Left err -> throw $ LocalProtocolError ("recvFrame: " `T.append` T.pack err) qt         Right (ver0, flags, stream, opcode, length) -> do             let ver = ver0 .&. 0x7f             when (ver /= protocolVersion) $-                throw $ LocalProtocolError $ "unexpected version " `T.append` T.pack (show ver)+                throw $ LocalProtocolError ("unexpected version " `T.append` T.pack (show ver)) qt             body <- if length == 0                 then pure B.empty                 else liftIO $ recvAll s (fromIntegral length)@@ -387,11 +396,11 @@ decodeCas :: CasType a => ByteString -> Either String a decodeCas bs = runGet getCas bs -decodeEltM :: (ProtoElt a, MonadIO m) => Text -> ByteString -> m a-decodeEltM what bs =+decodeEltM :: (ProtoElt a, MonadIO m) => Text -> ByteString -> Text -> m a+decodeEltM what bs qt =     case decodeElt bs of-        Left err -> throw $ LocalProtocolError $-            "can't parse" `T.append` what `T.append` ": " `T.append` T.pack err+        Left err -> throw $ LocalProtocolError+            ("can't parse" `T.append` what `T.append` ": " `T.append` T.pack err) qt         Right res -> return res  newtype Long a = Long { unLong :: a } deriving (Eq, Ord, Show, Read)@@ -449,22 +458,21 @@     deriving (Eq, Show)  -- | An exception that indicates an error originating in the Cassandra server.-data CassandraException = AuthenticationException Text-                        | ServerError Text-                        | ProtocolError Text-                        | BadCredentials Text-                        | UnavailableException Text Consistency Int Int-                        | Overloaded Text-                        | IsBootstrapping Text-                        | TruncateError Text-                        | WriteTimeout Text Consistency Int Int Text-                        | ReadTimeout Text Consistency Int Int Bool-                        | SyntaxError Text-                        | Unauthorized Text-                        | Invalid Text-                        | ConfigError Text-                        | AlreadyExists Text Keyspace Table-                        | Unprepared Text PreparedQueryID+data CassandraException = ServerError Text Text+                        | ProtocolError Text Text+                        | BadCredentials Text Text+                        | UnavailableException Text Consistency Int Int Text+                        | Overloaded Text Text+                        | IsBootstrapping Text Text+                        | TruncateError Text Text+                        | WriteTimeout Text Consistency Int Int Text Text+                        | ReadTimeout Text Consistency Int Int Bool Text+                        | SyntaxError Text Text+                        | Unauthorized Text Text+                        | Invalid Text Text+                        | ConfigError Text Text+                        | AlreadyExists Text Keyspace Table Text+                        | Unprepared Text PreparedQueryID Text     deriving (Show, Typeable)  instance Exception CassandraException where@@ -477,65 +485,66 @@ -- on the number of retries is likely to be a good idea. -- 'LocalProtocolError' probably indicates a corrupted database or driver -- bug.-data CassandraCommsError = LocalProtocolError Text-                         | ValueMarshallingException TransportDirection Text+data CassandraCommsError = AuthenticationException Text+                         | LocalProtocolError Text Text+                         | ValueMarshallingException TransportDirection Text Text                          | CassandraIOException IOException                          | ShortRead     deriving (Show, Typeable)  instance Exception CassandraCommsError -throwError :: MonadCatchIO m => ByteString -> m a-throwError bs = do+throwError :: MonadCatchIO m => Text -> ByteString -> m a+throwError qt bs = do     case runGet parseError bs of-        Left err -> throw $ LocalProtocolError $ "failed to parse error: " `T.append` T.pack err+        Left err -> throw $ LocalProtocolError ("failed to parse error: " `T.append` T.pack err) qt         Right exc -> throw exc   where     parseError :: Get CassandraException     parseError = do        code <- getWord32be        case code of-            0x0000 -> ServerError <$> getElt -            0x000A -> ProtocolError <$> getElt-            0x0100 -> BadCredentials <$> getElt+            0x0000 -> ServerError <$> getElt <*> pure qt +            0x000A -> ProtocolError <$> getElt <*> pure qt+            0x0100 -> BadCredentials <$> getElt <*> pure qt             0x1000 -> UnavailableException <$> getElt <*> getElt                                            <*> (fromIntegral <$> getWord32be)-                                           <*> (fromIntegral <$> getWord32be)-            0x1001 -> Overloaded <$> getElt-            0x1002 -> IsBootstrapping <$> getElt-            0x1003 -> TruncateError <$> getElt+                                           <*> (fromIntegral <$> getWord32be) <*> pure qt+            0x1001 -> Overloaded <$> getElt <*> pure qt+            0x1002 -> IsBootstrapping <$> getElt <*> pure qt+            0x1003 -> TruncateError <$> getElt <*> pure qt             0x1100 -> WriteTimeout <$> getElt <*> getElt                                    <*> (fromIntegral <$> getWord32be)                                    <*> (fromIntegral <$> getWord32be)-                                   <*> getElt+                                   <*> getElt <*> pure qt             0x1200 -> ReadTimeout <$> getElt <*> getElt                                   <*> (fromIntegral <$> getWord32be)                                   <*> (fromIntegral <$> getWord32be)-                                  <*> ((/=0) <$> getWord8)-            0x2000 -> SyntaxError <$> getElt-            0x2100 -> Unauthorized <$> getElt-            0x2200 -> Invalid <$> getElt-            0x2300 -> ConfigError <$> getElt-            0x2400 -> AlreadyExists <$> getElt <*> getElt <*> getElt-            0x2500 -> Unprepared <$> getElt <*> getElt+                                  <*> ((/=0) <$> getWord8) <*> pure qt+            0x2000 -> SyntaxError <$> getElt <*> pure qt+            0x2100 -> Unauthorized <$> getElt <*> pure qt+            0x2200 -> Invalid <$> getElt <*> pure qt+            0x2300 -> ConfigError <$> getElt <*> pure qt+            0x2400 -> AlreadyExists <$> getElt <*> getElt <*> getElt <*> pure qt+            0x2500 -> Unprepared <$> getElt <*> getElt <*> pure qt             _      -> fail $ "unknown error code 0x"++showHex code ""  introduce :: Pool -> StateT ActiveSession IO () introduce pool = do+    let qt = "<startup>"     sendFrame $ Frame [] 0 STARTUP $ encodeElt $ ([("CQL_VERSION", "3.0.0")] :: [(Text, Text)])-    fr <- recvFrame+    fr <- recvFrame qt     case frOpcode fr of         AUTHENTICATE -> throw $ AuthenticationException "authentication not implemented yet"         READY -> return ()-        ERROR -> throwError (frBody fr)-        op -> throw $ LocalProtocolError $ "introduce: unexpected opcode " `T.append` T.pack (show op)+        ERROR -> throwError qt (frBody fr)+        op -> throw $ LocalProtocolError ("introduce: unexpected opcode " `T.append` T.pack (show op)) qt     let Keyspace ksName = piKeyspace pool     let q = query $ "USE " `T.append` ksName :: Query Rows () ()     res <- executeInternal q () ONE     case res of         SetKeyspace ks -> return ()-        _ -> throw $ ProtocolError $ "expected SetKeyspace, but got " `T.append` T.pack (show res)-                              `T.append` " for query: " `T.append` T.pack (show q)+        _ -> throw $ LocalProtocolError ("expected SetKeyspace, but got " `T.append` T.pack (show res)) (queryText q)  withSession :: MonadCassandra m => (Pool -> StateT ActiveSession IO a) -> m a withSession code = do@@ -647,13 +656,23 @@ -- To define your own newtypes for Cassandra data, you only need to define 'getCas', -- 'putCas' and 'casType', like this: --+-- > newtype UserId = UserId UUID deriving (Eq, Show)+-- > -- > instance CasType UserId where -- >     getCas = UserId <$> getCas -- >     putCas (UserId i) = putCas i -- >     casType (UserId i) = casType i --+-- The same can be done more simply using the /GeneralizedNewtypeDeriving/ language+-- extension, e.g.+--+-- > {-# LANGUAGE GeneralizedNewtypeDeriving #-}+-- >+-- > ...+-- > newtype UserId = UserId UUID deriving (Eq, Show, CasType)+-- -- If you have a more complex type you want to store as a Cassandra blob, you could--- write an instance like this (assuming we're it's an instance of the /cereal/ package's+-- write an instance like this (assuming it's an instance of the /cereal/ package's -- 'Serialize' class): -- -- > instance CasType User where@@ -942,6 +961,9 @@     Query :: QueryID -> Text -> Query style i o     deriving Show +queryText :: Query s i o -> Text+queryText (Query _ txt) = txt+ instance IsString (Query style i o) where     fromString = query . T.pack @@ -1015,18 +1037,18 @@         Just pq -> return pq         Nothing -> do             sendFrame $ Frame [] 0 PREPARE $ encodeElt (Long cql)-            fr <- recvFrame+            fr <- recvFrame cql             case frOpcode fr of                 RESULT -> do-                    res <- decodeEltM "RESULT" (frBody fr)+                    res <- decodeEltM "RESULT" (frBody fr) cql                     case (res :: Result [Maybe ByteString]) of                         Prepared pqid meta -> do                             let pq = PreparedQuery pqid meta                             modify $ \act -> act { actQueryCache = M.insert qid pq (actQueryCache act) }                             return pq-                        _ -> throw $ LocalProtocolError $ "prepare: unexpected result " `T.append` T.pack (show res)-                ERROR -> throwError (frBody fr)-                _ -> throw $ LocalProtocolError $ "prepare: unexpected opcode " `T.append` T.pack (show (frOpcode fr))+                        _ -> throw $ LocalProtocolError ("prepare: unexpected result " `T.append` T.pack (show res)) cql+                ERROR -> throwError cql (frBody fr)+                _ -> throw $ LocalProtocolError ("prepare: unexpected opcode " `T.append` T.pack (show (frOpcode fr))) cql  data CodingFailure = Mismatch Int CType CType                    | WrongNumber Int Int@@ -1270,7 +1292,7 @@ executeInternal query i cons = do     pq@(PreparedQuery pqid queryMeta) <- prepare query     values <- case encodeValues i (metadataTypes queryMeta) of-        Left err -> throw $ ValueMarshallingException TransportSending $ T.pack $ show err+        Left err -> throw $ ValueMarshallingException TransportSending (T.pack $ show err) (queryText query)         Right values -> return values     sendFrame $ Frame [] 0 EXECUTE $ runPut $ do         putElt pqid@@ -1283,11 +1305,11 @@                     putWord32be (fromIntegral $ B.length enc)                      putByteString enc         putElt cons-    fr <- recvFrame+    fr <- recvFrame (queryText query)     case frOpcode fr of-        RESULT -> decodeEltM "RESULT" (frBody fr)-        ERROR -> throwError (frBody fr)-        _ -> throw $ LocalProtocolError $ "execute: unexpected opcode " `T.append` T.pack (show (frOpcode fr))+        RESULT -> decodeEltM "RESULT" (frBody fr) (queryText query)+        ERROR -> throwError (queryText query) (frBody fr)+        _ -> throw $ LocalProtocolError ("execute: unexpected opcode " `T.append` T.pack (show (frOpcode fr))) (queryText query)  -- | Execute a query that returns rows. executeRows :: (MonadCassandra m, CasValues i, CasValues o) =>@@ -1298,9 +1320,8 @@ executeRows cons q i = do     res <- executeRaw q i cons     case res of-        RowsResult meta rows -> decodeRows meta rows-        _ -> throw $ ProtocolError $ "expected Rows, but got " `T.append` T.pack (show res)-                              `T.append` " for query: " `T.append` T.pack (show q)+        RowsResult meta rows -> decodeRows q meta rows+        _ -> throw $ LocalProtocolError ("expected Rows, but got " `T.append` T.pack (show res)) (queryText q)  -- | Helper for 'executeRows' useful in situations where you are only expecting one row -- to be returned.@@ -1313,11 +1334,11 @@     rows <- executeRows cons q i     return $ listToMaybe rows -decodeRows :: (MonadCatchIO m, CasValues values) => Metadata -> [[Maybe ByteString]] -> m [values]-decodeRows meta rows0 = do+decodeRows :: (MonadCatchIO m, CasValues values) => Query Rows any_i values -> Metadata -> [[Maybe ByteString]] -> m [values]+decodeRows query meta rows0 = do     let rows1 = flip map rows0 $ \cols -> decodeValues (zip (metadataTypes meta) cols)     case lefts rows1 of-        (err:_) -> throw $ ValueMarshallingException TransportReceiving $ T.pack $ show err+        (err:_) -> throw $ ValueMarshallingException TransportReceiving (T.pack $ show err) (queryText query)         [] -> return ()     let rows2 = flip map rows1 $ \(Right v) -> v     return $ rows2@@ -1332,8 +1353,7 @@     res <- executeRaw q i cons     case res of         Void -> return ()-        _ -> throw $ ProtocolError $ "expected Void, but got " `T.append` T.pack (show res)-                              `T.append` " for query: " `T.append` T.pack (show q)+        _ -> throw $ LocalProtocolError ("expected Void, but got " `T.append` T.pack (show res)) (queryText q)  -- | Execute a schema change, such as creating or dropping a table. executeSchema :: (MonadCassandra m, CasValues i) =>@@ -1345,8 +1365,7 @@     res <- executeRaw q i cons     case res of         SchemaChange ch ks ta -> return (ch, ks, ta)-        _ -> throw $ ProtocolError $ "expected SchemaChange, but got " `T.append` T.pack (show res)-                              `T.append` " for query: " `T.append` T.pack (show q)+        _ -> throw $ LocalProtocolError ("expected SchemaChange, but got " `T.append` T.pack (show res)) (queryText q)  -- | A helper for extracting the types from a metadata definition. metadataTypes :: Metadata -> [CType]
cassandra-cql.cabal view
@@ -1,5 +1,5 @@ name:                cassandra-cql-version:             0.2.0.1+version:             0.2.0.2 synopsis:            Haskell client for Cassandra's CQL protocol description:            Haskell client for Cassandra's CQL protocol