Idiomatic F# extensions for the C# RethinkDB driver https://bitbadger.solutions/open-source/rethinkdb-driver-fsharp/
Go to file
Daniel J. Summers f23f7b90e9 WIP toward completeness
- Add opt args for the run command
- Support Task/Async/sync for all run/write/result cmds
- Define builder using funcs from Functions module
- Functions module no longer auto-opened
- Update README with some of the above
2022-04-21 20:36:30 -04:00
src WIP toward completeness 2022-04-21 20:36:30 -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 WIP toward completeness 2022-04-21 20:36:30 -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:
open RethinkDb.Driver.FSharp.Functions

/// 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):
open RethinkDb.Driver.FSharp

/// 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. Also, while CEs now support overloading (thank you F# 6 developers!), they do not detect if the first value in the tupled arguments is different. This is most noticeable once result* or write* commands have been issued; these support Task<'T>, Async<'T>, and synchronous 'T operations, but the follow-on commands will be different (e.x. withRetryDefault (tasks) vs. withAsyncRetryDefault vs. withSyncRetryDefault). There are also versions of these that support optional arguments (for all) and cancellation tokens (for task/async).

The functions show this pattern throughout, as functions in a module 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.G("age").Eq 30)
// and
filterJS "function (row) { return 30 == row['age'] }"

Functions that support optional arguments end with WithOptArgs; those that support cancellation tokens end with WithCancel; and, those that support both end with WithOptArgsAndCancel.

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!