FsCassy


Namespaces

FsCassy is organized into 3 APIs:

  • Statement API - compositional DSL for formulating the statements (includes pretty-printer)
  • Cassandra API - modules for working specifically with Cassandra (cluster connections, the interperter, etc)
  • InMem API - modules for unit-testing the code that uses Statement API (note that not all Cassandra options are covered by in-mem implementation)

Statements

The statements while composed are detached from implementation that will execute them, but are fully type-checking everything that goes into them (except for PreparedStatement). The Statement API directly reflects Cassandra operations, here are some of the examples:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
#r "FsCassy.dll"
#r "Cassandra.dll"
open FsCassy

type SomeMappedTable = {x:int}

let exampleWhere : Statement<SomeMappedTable,_> =
        table
    >>= where (Quote.X(fun x -> x.x = 0)) 
    >>= read

let exampleTake : Statement<SomeMappedTable,_> =
        table
    >>= take 1
    >>= read

let exampleCount : Statement<SomeMappedTable,_> =
        table
    >>= withConsistency Consistency.Any
    >>= count

let exampleUpdate : Statement<SomeMappedTable,_> =
        table
    >>= where (Quote.X(fun x -> x.x = 0))
    >>= select (Quote.X(fun x -> { x with x = 10}))
    >>= update
    >>= withConsistency Consistency.Any
    >>= execute

let exampleUpdateIf : Statement<SomeMappedTable,_> =
        table
    >>= where (Quote.X(fun x -> x.x = 0))
    >>= select (Quote.X(fun x -> { x with x = 10}))
    >>= updateIf (Quote.X(fun x -> x.x = 0))
    >>= withConsistency Consistency.Any
    >>= execute

let exampleDelete : Statement<SomeMappedTable,_> =
        table
    >>= where (Quote.X(fun x -> x.x = 0))
    >>= delete
    >>= execute

let exampleUpsert : Statement<SomeMappedTable,_> =
        table
    >>= upsert {x = 100}
    >>= withConsistency Consistency.Any
    >>= execute
        

Prepared statements

Prepared statements are a fallback mechanism: some of the CQL features are not implemented (or not working as inteded) via the .NET driver. See Cassandra docs for more information.

For most operations you will be able to use the provided DSL.

Interpreters

Interpreters parse statements and carry out the actual work, following functions are available:

  • Cassandra interpreter
    Cassandra interpreter uses Table API and relies on the same type mapping facilities.

  • Pretty printer
    Humand-readable rough approximmation of the statement and it's arguments.

  • In-Mem interpreter
    Executes statements against a predefined list.

The library also defines an interface with an equivalent function, see the relevant discussion here.

You don't have to use this interface, you can define your own or even make do without one using SRTP. If you do please consider contributing, we'd love to see what you come up with.

Cassandra driver and FsCassy API

FsCassy exposes a small set of functions that make it easier to construct the relevant parts, thier use is completely optional:

  • Cluster connectivity
  • Session construction and parametrization
  • LINQ Table construction

The purpose of these (reference) implementations is to construct the arguments for the interpreter. You may want to have your own implementations instead using the official Cassandra API.

InMem API

InMem implemenetation of the interpreter takes a ResizeArray as the source to work agains and can be supplied instead of Cassandra interpreter:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
let xs = [ {x = 1}
           {x = 2}
           {x = 3}
           {x = 4}
           {x = 0}
           {x = 5}
           {x = 0}
           {x = 6} ]

let ``InMem reads``() = 
    table >>= read 
    |> InMem.Interpreter.execute (ResizeArray xs) 
    |> Async.RunSynchronously
type SomeMappedTable =
  {x: int;}

Full name: Tutorial.SomeMappedTable
SomeMappedTable.x: int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val exampleWhere : obj

Full name: Tutorial.exampleWhere
val exampleTake : obj

Full name: Tutorial.exampleTake
val exampleCount : obj

Full name: Tutorial.exampleCount
val exampleUpdate : obj

Full name: Tutorial.exampleUpdate
val exampleUpdateIf : obj

Full name: Tutorial.exampleUpdateIf
val exampleDelete : obj

Full name: Tutorial.exampleDelete
val exampleUpsert : obj

Full name: Tutorial.exampleUpsert
val xs : SomeMappedTable list

Full name: Tutorial.xs
val ( InMem reads ) : unit -> 'a

Full name: Tutorial.( InMem reads )
type ResizeArray<'T> = System.Collections.Generic.List<'T>

Full name: Microsoft.FSharp.Collections.ResizeArray<_>
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member Choice : computations:seq<Async<'T option>> -> Async<'T option>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Fork me on GitHub