Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Use CasType more pervasively

  • Loading branch information...
commit 171337d405cc7a6aed82a0e838e2029fe96c3605 1 parent 2325e02
@ozataman ozataman authored
View
2  cassy.cabal
@@ -71,6 +71,7 @@ Library
, cassandra-thrift >= 0.8
, resource-pool
, errors
+ , data-default
test-suite test
@@ -95,6 +96,7 @@ test-suite test
, cassandra-thrift >= 0.8
, resource-pool
, errors
+ , data-default
, test-framework >= 0.6
, test-framework-quickcheck2 >= 0.2.12.2
View
5 src/Database/Cassandra/Basic.hs
@@ -34,6 +34,7 @@ module Database.Cassandra.Basic
-- * Filtering
, Selector(..)
+ , range
, Order(..)
, reverseOrder
, KeySelector(..)
@@ -307,10 +308,10 @@ delete cf k s cl = withCassandraPool $ \ Cassandra {..} -> do
cpAll = T.ColumnPath (Just cf) Nothing Nothing
-- just a single column
- cpCol name = T.ColumnPath (Just cf) Nothing (Just name)
+ cpCol name = T.ColumnPath (Just cf) Nothing (Just (encodeCas name))
-- scope column by supercol
- cpSCol sc name = T.ColumnPath (Just cf) (Just sc) (Just name)
+ cpSCol sc name = T.ColumnPath (Just cf) (Just (encodeCas sc)) (Just (encodeCas name))
View
44 src/Database/Cassandra/JSON.hs
@@ -39,6 +39,7 @@ module Database.Cassandra.JSON
-- * Cassandra Operations
, get
+ , get_
, getCol
, getMulti
, insertCol
@@ -53,11 +54,14 @@ module Database.Cassandra.JSON
, ColumnFamily (..)
, ConsistencyLevel (..)
, CassandraException (..)
+
+ -- * Filtering
, Selector (..)
- , KeySelector (..)
- , KeyRangeType (..)
+ , range
, Order(..)
, reverseOrder
+ , KeySelector (..)
+ , KeyRangeType (..)
-- * Helpers
, CKey (..)
@@ -142,10 +146,11 @@ type RowKey = Text
-- This method may throw a 'CassandraException' for all exceptions other than
-- 'NotFoundException'.
modify
- :: (MonadCassandra m, ToJSON a, FromJSON a)
+ :: (MonadCassandra m, ToJSON a, FromJSON a, CasType k)
=> ColumnFamily
-> RowKey
- -> ColumnName
+ -> k
+ -- ^ Column name; anything in CasType
-> ConsistencyLevel
-- ^ Read quorum
-> ConsistencyLevel
@@ -158,7 +163,7 @@ modify
modify cf k cn rcl wcl f =
let
k' = toColKey k
- cn' = toColKey cn
+ cn' = encodeCas cn
execF prev = do
(fres, b) <- f prev
case fres of
@@ -183,10 +188,11 @@ modify cf k cn rcl wcl f =
-- This method may throw a 'CassandraException' for all exceptions other than
-- 'NotFoundException'.
modify_
- :: (MonadCassandra m, ToJSON a, FromJSON a)
+ :: (MonadCassandra m, ToJSON a, FromJSON a, CasType k)
=> ColumnFamily
-> RowKey
- -> ColumnName
+ -> k
+ -- ^ Column name; anything in CasType
-> ConsistencyLevel
-- ^ Read quorum
-> ConsistencyLevel
@@ -241,6 +247,23 @@ get cf k s cl = do
-------------------------------------------------------------------------------
+-- | A version of 'get' that discards the column names for the common
+-- scenario. Useful because you would otherwise be forced to manually
+-- supply type signatures to get rid of the 'CasType' ambiguity.
+get_
+ :: (MonadCassandra m, FromJSON a)
+ => ColumnFamily
+ -> RowKey
+ -> Selector
+ -- ^ A slice selector
+ -> ConsistencyLevel
+ -> m [a]
+get_ cf k s cl = do
+ (res :: [(LB.ByteString, a)]) <- get cf k s cl
+ return $ map snd res
+
+
+-------------------------------------------------------------------------------
data KeySelector
= Keys [RowKey]
| KeyRange KeyRangeType RowKey RowKey Int32
@@ -272,14 +295,15 @@ getMulti cf ks s cl = do
-------------------------------------------------------------------------------
-- | Get a single column from a single row
getCol
- :: (MonadCassandra m, FromJSON a)
+ :: (MonadCassandra m, FromJSON a, CasType k)
=> ColumnFamily
-> RowKey
- -> ColumnName
+ -> k
+ -- ^ Column name; anything in 'CasType'
-> ConsistencyLevel
-> m (Maybe a)
getCol cf rk ck cl = do
- res <- CB.getCol cf (toColKey rk) (toColKey ck) cl
+ res <- CB.getCol cf (toColKey rk) (encodeCas ck) cl
case res of
Nothing -> return Nothing
Just res' -> do
View
8 src/Database/Cassandra/Pack.hs
@@ -232,10 +232,10 @@ instance (CasType a, CasType b, CasType c, CasType d) => CasType (a, b, c, Exclu
<*> (Exclusive <$> getSegment)
-instance CasType a => CasType [a] where
- encodeCas as = runPut $ do
- mapM (flip putSegment sep) $ init as
- putSegment (last as) end
+-- instance CasType a => CasType [a] where
+-- encodeCas as = runPut $ do
+-- mapM (flip putSegment sep) $ init as
+-- putSegment (last as) end
-------------------------------------------------------------------------------
View
73 src/Database/Cassandra/Types.hs
@@ -1,10 +1,11 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE PatternGuards #-}
-{-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TypeSynonymInstances #-}
module Database.Cassandra.Types where
@@ -15,8 +16,10 @@ import Control.Monad
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy.Char8 as LB
+import Data.Default
import Data.Generics
import Data.Int (Int32, Int64)
+import Data.List
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
@@ -26,6 +29,8 @@ import Data.Time
import Data.Time.Clock.POSIX
import qualified Database.Cassandra.Thrift.Cassandra_Types as C
-------------------------------------------------------------------------------
+import Database.Cassandra.Pack
+-------------------------------------------------------------------------------
-- | A 'Key' range selector to use with 'getMulti'.
@@ -50,21 +55,56 @@ mkKeyRange (KeyRange ty st end cnt) = case ty of
InclusiveRange -> C.KeyRange (Just st) (Just end) Nothing Nothing (Just cnt)
WrapAround -> C.KeyRange Nothing Nothing (Just $ LB.unpack st) (Just $ LB.unpack end) (Just cnt)
+
+-------------------------------------------------------------------------------
-- | A column selector/filter statement for queries.
--
-- Remember that SuperColumns are always fully deserialized, so we don't offer
-- a way to filter columns within a 'SuperColumn'.
+--
+-- Column names and ranges are specified by any type that can be
+-- packed into a Cassandra column using the 'CasType' typeclass.
data Selector =
All
-- ^ Return everything in 'Row'
- | ColNames [ColumnName]
+ | forall a. CasType a => ColNames [a]
-- ^ Return specific columns or super-columns depending on the 'ColumnFamily'
- | SupNames ColumnName [ColumnName]
+ | forall a b. (CasType a, CasType b) => SupNames a [b]
-- ^ When deleting specific columns in a super column
- | Range (Maybe ColumnName) (Maybe ColumnName) Order Int32
- -- ^ Return a range of columns or super-columns
- deriving (Show)
+ | forall a b. (CasType a, CasType b) => Range {
+ rangeStart :: Maybe a
+ , rangeEnd :: Maybe b
+ , rangeOrder :: Order
+ , rangeLimit :: Int32
+ }
+ -- ^ Return a range of columns or super-columns.
+-------------------------------------------------------------------------------
+-- | A default starting point for range 'Selector'. Use this so you
+-- don't run into ambiguous type variables when using Nothing.
+--
+-- > range = Range (Nothing :: Maybe ByteString) (Nothing :: Maybe ByteString) Regular 1024
+range = Range (Nothing :: Maybe ByteString) (Nothing :: Maybe ByteString) Regular 1024
+
+
+
+instance Default Selector where
+ def = All
+
+instance Show Selector where
+ show All = "All"
+ show (ColNames cns) = concat
+ ["ColNames: ", intercalate ", " $ map showCas cns]
+ show (SupNames cn cns) = concat
+ ["SuperCol: ", showCas cn, "; Cols: ", intercalate ", " (map showCas cns)]
+ show (Range a b order i) = concat
+ [ "Range from ", maybe "Nothing" showCas a, " to ", maybe "Nothing" showCas b
+ , " order ", show order, " max ", show i, " items." ]
+
+
+-------------------------------------------------------------------------------
+showCas :: CasType a => a -> String
+showCas t = LB.unpack . encodeCas $ t
-------------------------------------------------------------------------------
@@ -74,11 +114,11 @@ mkPredicate s =
allRange = C.SliceRange (Just "") (Just "") (Just False) (Just 5000)
in case s of
All -> C.SlicePredicate Nothing (Just allRange)
- ColNames ks -> C.SlicePredicate (Just ks) Nothing
+ ColNames ks -> C.SlicePredicate (Just (map encodeCas ks)) Nothing
Range st end ord cnt ->
let
- st' = st `mplus` Just ""
- end' = end `mplus` Just ""
+ st' = fmap encodeCas st `mplus` Just ""
+ end' = fmap encodeCas end `mplus` Just ""
in C.SlicePredicate Nothing
(Just (C.SliceRange st' end' (Just $ renderOrd ord) (Just cnt)))
@@ -134,7 +174,8 @@ type Row = [Column]
------------------------------------------------------------------------------
--- | A short-hand for creating key-value 'Column' values
+-- | A short-hand for creating key-value 'Column' values. This is
+-- pretty low level; you probably want to use 'packCol'.
col :: ByteString -> ByteString -> Column
col k v = Column k v Nothing Nothing
Please sign in to comment.
Something went wrong with that request. Please try again.