Idiomatic F# extensions for the C# RethinkDB driver https://bitbadger.solutions/open-source/rethinkdb-driver-fsharp/
Go to file
2022-04-19 12:49:31 -04:00
src Fix table addressing 2022-04-19 12:49:31 -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 Fix table addressing 2022-04-19 12:49:31 -04:00

RethinkDb.Driver.FSharp

Idiomatic F# extensions for the C# RethinkDB driver

Nuget (with prereleases)

Using

Install the NuGet package RethinkDb.Driver.FSharp. You will need to specify pre-release, as the package has an alpha designation at this time.

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 (CE):
/// string -> (IConnection -> Task<Post>)
let fetchPost (postId : string) =
    rethink<Post> {
        withTable "Blog.Post"
        get postId
        result
        withRetryDefault
    }
  • A standard way to translate JSON into a strongly-typed configuration:
/// type: DataConfig
let config = DataConfig.fromJsonFile "data-config.json"
// OR
let config = DataConfig.fromConfiguration (config.GetSection "RethinkDB")

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

/// type: Post (utilizing either example above)
// (within a task CE)
let! post = fetchPost "the-post-id" conn
  • Robust queries

The RethinkDB connection is generally stored as a singleton. Over time, this connection can lose its connection to the server. Both the CE and functions have withRetryDefault, which will retry a failed command up to 3 times (4 counting the initial try), waiting 200ms, 500ms, and 1 second between the respective attempts. There are other options as well; withRetryOnce will retry one time immediately. withRetry takes a list of floats, which will be interpreted as seconds to delay between each retry; it will retry until it has exhausted the delays.

The examples above both use the default retry logic.

  • Only rename functions/methods where required

Within the CE, there are a few differing names, mostly notably at the start (selecting databases and tables); this is to allow for a more natural language flow. Its names may change in the 0.8.x series; it is the most alpha part of the project at this point.

The functions do have to change a bit, since they do not support overloading; an example for filter is below.

// 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'] }"

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.


If you are using the project, feel free to file issues about your pain points; there is no substitute for real-world feedback!