Idiomatic F# extensions for the C# RethinkDB driver https://bitbadger.solutions/open-source/rethinkdb-driver-fsharp/
Go to file
Daniel J. Summers 2e749e1a27 Prep for 0.8.0
- Functions now prefer tasks
- Put retry logic in its own module; both CE and functions use it
- Annotated types where necessary for smooth F# 6 implicit casting
2022-04-18 22:31:48 -04:00
src Prep for 0.8.0 2022-04-18 22:31:48 -04:00
.gitignore Initial commit 2017-07-15 08:05:37 -05:00
appveyor.yml Update CI settings 2022-04-11 23:38:42 -04:00
LICENSE Initial extraction from other project 2017-07-16 20:18:47 -05:00
README.md Prep for 0.8.0 2022-04-18 22:31:48 -04:00

RethinkDb.Driver.FSharp

Idiomatic F# extensions for the C# RethinkDB driver

Licensing

While no specific additional license restrictions exist for this project, there are modifications to the Apache v2 license on this project's dependencies. Please see the heading on the C# driver page for details.

Using

It is still early days on this project; however, AppVeyor CI provides a NuGet feed that builds packages for each commit.

Goals

The goal is to provide:

  • A composable pipeline for creating ReQL statements:
/// string -> (IConnection -> Task<Post>)
let fetchPost (postId : string) =
    fromDb "Blog"
    |> table "Post"
    |> get postId
    |> runResult<Post>
    |> withRetryDefault
  • An F# domain-specific language (DSL) using a rethink computation expression:
/// string -> (IConnection -> Task<Post>)
let fetchPost (postId : string) =
    rethink<Post> {
        withTableInDb "Post" "Blog"
        get postId
        result
        withRetryDefault
    }
  • A standard way to translate JSON into a strongly-typed configuration:
/// type: DataConfig
let config = DataConfig.fromJsonFile "data-config.json"

/// type: IConnection
let conn = config.Connect ()

/// type: Post (utilizing either example above)
let post = fetchPost "the-post-id" conn |> Async.RunSynchronously
  • Only rename functions/methods where required
// Function names cannot be polymorphic the way object-oriented methods can, so filter's three overloads become
filter (r.HashMap ("age", 30))
// and
filterFunc (fun row -> row.["age"].Eq(30))
// and
filterJS "function (row) { return 30 == row['age'] }"

The composable pipeline and the JSON configuration are the early goals, as the computation expression will utilize the same composition as those functions.