Add strongly-typed opt args

- Add between to CE
- Return default db from calls if name is blank
This commit is contained in:
Daniel J. Summers 2022-04-19 10:38:29 -04:00
parent 7f98891ebd
commit eab4cb80b0
4 changed files with 374 additions and 80 deletions

View File

@ -3,17 +3,10 @@ module RethinkDb.Driver.FSharp.RethinkBuilder
open RethinkDb.Driver open RethinkDb.Driver
open RethinkDb.Driver.Ast open RethinkDb.Driver.Ast
open RethinkDb.Driver.FSharp
open RethinkDb.Driver.Net open RethinkDb.Driver.Net
open System.Threading.Tasks open System.Threading.Tasks
/// Options for RethinkDB indexes
type IndexOption =
/// Index multiple values in the given field
| Multi
/// Create a geospatial index
| Geospatial
/// Computation Expression builder for RethinkDB queries /// Computation Expression builder for RethinkDB queries
type RethinkBuilder<'T> () = type RethinkBuilder<'T> () =
@ -31,6 +24,25 @@ type RethinkBuilder<'T> () =
member _.Yield _ = RethinkDB.R member _.Yield _ = RethinkDB.R
// database/table identification
/// Specify a database for further commands
[<CustomOperation "withDb">]
member _.Db (expr : RethinkDB, db : string) = match db with "" -> expr.Db () | _ -> expr.Db db
/// Specify a table in the default database
[<CustomOperation "withTable">]
member _.TableInDefaultDb (expr : RethinkDB, table : string) = expr.Table table
/// Specify a table in a specific database
[<CustomOperation "withTable">]
member _.Table (db : Db, table : string) = db.Table table
/// Create an equality join with another table
[<CustomOperation "eqJoin">]
member _.EqJoin (expr : ReqlExpr, field : string, otherTable : string) =
expr.EqJoin (field, RethinkDB.R.Table otherTable)
// meta queries (tables, indexes, etc.) // meta queries (tables, indexes, etc.)
/// List all databases /// List all databases
@ -46,16 +58,16 @@ type RethinkBuilder<'T> () =
member _.TableList (r : RethinkDB) = r.TableList () member _.TableList (r : RethinkDB) = r.TableList ()
/// List all tables for the specified database /// List all tables for the specified database
[<CustomOperation "tableListWithDb">] [<CustomOperation "tableList">]
member _.TableListWithDb (r : RethinkDB, db : string) = r.Db(db).TableList () member this.TableList (r : RethinkDB, db : string) = this.Db(r, db).TableList ()
/// Create a table in the default database /// Create a table in the default database
[<CustomOperation "tableCreate">] [<CustomOperation "tableCreate">]
member _.TableCreate (r : RethinkDB, table : string) = r.TableCreate table member _.TableCreate (r : RethinkDB, table : string) = r.TableCreate table
/// Create a table in the default database /// Create a table in the default database
[<CustomOperation "tableCreateWithDb">] [<CustomOperation "tableCreate">]
member _.TableCreateWithDb (r : RethinkDB, table : string, db : string) = r.Db(db).TableCreate table member _.TableCreate (db : Db, table : string) = db.TableCreate table
/// List all indexes for a table /// List all indexes for a table
[<CustomOperation "indexList">] [<CustomOperation "indexList">]
@ -65,33 +77,19 @@ type RethinkBuilder<'T> () =
[<CustomOperation "indexCreate">] [<CustomOperation "indexCreate">]
member _.IndexCreate (tbl : Table, index : string) = tbl.IndexCreate index member _.IndexCreate (tbl : Table, index : string) = tbl.IndexCreate index
/// Create an index for a table, specifying an optional argument
[<CustomOperation "indexCreate">]
member this.IndexCreate (tbl : Table, index : string, opts : IndexCreateOptArg list) =
this.IndexCreate (tbl, index) |> IndexCreateOptArg.apply opts
/// Create an index for a table, using a function to calculate the index /// Create an index for a table, using a function to calculate the index
[<CustomOperation "indexCreate">] [<CustomOperation "indexCreate">]
member _.IndexCreate (tbl : Table, index : string, f : ReqlExpr -> obj) = tbl.IndexCreate (index, ReqlFunction1 f) member _.IndexCreate (tbl : Table, index : string, f : ReqlExpr -> obj) = tbl.IndexCreate (index, ReqlFunction1 f)
/// Specify options for certain types of indexes /// Create an index for a table, using a function to calculate the index
[<CustomOperation "indexOption">] [<CustomOperation "indexCreate">]
member _.IndexOption (idx : IndexCreate, opt : IndexOption) = member this.IndexCreate (tbl : Table, index : string, f : ReqlExpr -> obj, opts : IndexCreateOptArg list) =
idx.OptArg ((match opt with Multi -> "multi" | Geospatial -> "geo"), true) this.IndexCreate (tbl, index, f) |> IndexCreateOptArg.apply opts
// database/table identification
/// Specify a database for further commands
[<CustomOperation "withDb">]
member _.Db (expr : RethinkDB, db : string) = expr.Db db
/// Specify a table in the default database
[<CustomOperation "withTable">]
member _.TableInDefaultDb (expr : RethinkDB, table : string) = expr.Table table
/// Specify a table in a specific database
[<CustomOperation "withTableInDb">]
member _.Table (expr : RethinkDB, table : string, db : string) = expr.Db(db).Table table
/// Create an equality join with another table
[<CustomOperation "eqJoin">]
member _.EqJoin (expr : ReqlExpr, field : string, otherTable : string) =
expr.EqJoin (field, RethinkDB.R.Table otherTable)
// data retrieval / manipulation // data retrieval / manipulation
@ -99,10 +97,15 @@ type RethinkBuilder<'T> () =
[<CustomOperation "get">] [<CustomOperation "get">]
member _.Get (tbl : Table, key : obj) = tbl.Get key member _.Get (tbl : Table, key : obj) = tbl.Get key
/// Get all documents matching the given primary key value
[<CustomOperation "getAll">]
member _.GetAll (tbl : Table, keys : obj list) =
tbl.GetAll (Array.ofList keys)
/// Get all documents matching the given index value /// Get all documents matching the given index value
[<CustomOperation "getAll">] [<CustomOperation "getAll">]
member _.GetAll (tbl : Table, keys : obj list, index : string) = member this.GetAll (tbl : Table, keys : obj list, index : string) =
tbl.GetAll(Array.ofList keys).OptArg ("index", index) this.GetAll(tbl, keys).OptArg ("index", index)
/// Skip a certain number of results /// Skip a certain number of results
[<CustomOperation "skip">] [<CustomOperation "skip">]
@ -120,18 +123,57 @@ type RethinkBuilder<'T> () =
[<CustomOperation "filter">] [<CustomOperation "filter">]
member _.Filter (expr : ReqlExpr, field : string, value : obj) = expr.Filter (fieldsToMap [ field, value ]) member _.Filter (expr : ReqlExpr, field : string, value : obj) = expr.Filter (fieldsToMap [ field, value ])
/// Filter a query by a single field value, including an optional argument
[<CustomOperation "filter">]
member this.Filter (expr : ReqlExpr, field : string, value : obj, opt : FilterOptArg) =
this.Filter (expr, field, value) |> FilterOptArg.apply opt
/// Filter a query by multiple field values /// Filter a query by multiple field values
[<CustomOperation "filter">] [<CustomOperation "filter">]
member _.Filter (expr : ReqlExpr, filter : (string * obj) list) = expr.Filter (fieldsToMap filter) member _.Filter (expr : ReqlExpr, filter : (string * obj) list) = expr.Filter (fieldsToMap filter)
/// Filter a query by multiple field values, including an optional argument
[<CustomOperation "filter">]
member this.Filter (expr : ReqlExpr, filter : (string * obj) list, opt : FilterOptArg) =
this.Filter (expr, filter) |> FilterOptArg.apply opt
/// Filter a query by a function /// Filter a query by a function
[<CustomOperation "filter">] [<CustomOperation "filter">]
member _.Filter (expr : ReqlExpr, f : ReqlExpr -> obj) = expr.Filter (ReqlFunction1 f) member _.Filter (expr : ReqlExpr, f : ReqlExpr -> obj) = expr.Filter (ReqlFunction1 f)
/// Filter a query by a function, including an optional argument
[<CustomOperation "filter">]
member this.Filter (expr : ReqlExpr, f : ReqlExpr -> obj, opt : FilterOptArg) =
this.Filter (expr, f) |> FilterOptArg.apply opt
/// Filter a query by multiple functions (has the effect of ANDing them) /// Filter a query by multiple functions (has the effect of ANDing them)
[<CustomOperation "filter">] [<CustomOperation "filter">]
member _.Filter (expr : ReqlExpr, fs : (ReqlExpr -> obj) list) = member _.Filter (expr : ReqlExpr, fs : (ReqlExpr -> obj) list) : Filter =
fs |> List.fold (fun (e : ReqlExpr) f -> e.Filter (ReqlFunction1 f)) expr (fs |> List.fold (fun (e : ReqlExpr) f -> e.Filter (ReqlFunction1 f)) expr) :?> Filter
/// Filter a query by multiple functions (has the effect of ANDing them), including an optional argument
[<CustomOperation "filter">]
member this.Filter (expr : ReqlExpr, fs : (ReqlExpr -> obj) list, opt : FilterOptArg) =
this.Filter (expr, fs) |> FilterOptArg.apply opt
/// Filter a query using a JavaScript expression
[<CustomOperation "filter">]
member _.Filter (expr : ReqlExpr, js : string) = expr.Filter (Javascript js)
/// Filter a query using a JavaScript expression, including an optional argument
[<CustomOperation "filter">]
member this.Filter (expr : ReqlExpr, js : string, opt : FilterOptArg) =
this.Filter (expr, js) |> FilterOptArg.apply opt
/// Filter a query by a range of values
[<CustomOperation "between">]
member _.Between (expr : ReqlExpr, lower : obj, upper : obj) =
expr.Between (lower, upper)
/// Filter a query by a range of values, using optional arguments
[<CustomOperation "between">]
member this.Between (expr : ReqlExpr, lower : obj, upper : obj, opts : BetweenOptArg list) =
this.Between (expr, lower, upper) |> BetweenOptArg.apply opts
/// Map fields for the current query /// Map fields for the current query
[<CustomOperation "map">] [<CustomOperation "map">]
@ -169,18 +211,38 @@ type RethinkBuilder<'T> () =
[<CustomOperation "insert">] [<CustomOperation "insert">]
member _.Insert (tbl : Table, doc : obj) = tbl.Insert doc member _.Insert (tbl : Table, doc : obj) = tbl.Insert doc
/// Insert a document into the given table, using optional arguments
[<CustomOperation "insert">]
member this.Insert (tbl : Table, doc : obj, opts : InsertOptArg list) =
this.Insert (tbl, doc) |> InsertOptArg.apply opts
/// Update specific fields in a document /// Update specific fields in a document
[<CustomOperation "update">] [<CustomOperation "update">]
member _.Update (expr : ReqlExpr, fields : (string * obj) list) = expr.Update (fieldsToMap fields) member _.Update (expr : ReqlExpr, fields : (string * obj) list) = expr.Update (fieldsToMap fields)
/// Update specific fields in a document, using optional arguments
[<CustomOperation "update">]
member this.Update (expr : ReqlExpr, fields : (string * obj) list, args : UpdateOptArg list) =
this.Update (expr, fields) |> UpdateOptArg.apply args
/// Replace the current query with the specified document /// Replace the current query with the specified document
[<CustomOperation "replace">] [<CustomOperation "replace">]
member _.Replace (expr : ReqlExpr, doc : obj) = expr.Replace doc member _.Replace (expr : ReqlExpr, doc : obj) = expr.Replace doc
/// Replace the current query with the specified document, using optional arguments
[<CustomOperation "replace">]
member this.Replace (expr : ReqlExpr, doc : obj, args : ReplaceOptArg list) =
this.Replace (expr, doc) |> ReplaceOptArg.apply args
/// Delete the document(s) identified by the current query /// Delete the document(s) identified by the current query
[<CustomOperation "delete">] [<CustomOperation "delete">]
member _.Delete (expr : ReqlExpr) = expr.Delete () member _.Delete (expr : ReqlExpr) = expr.Delete ()
/// Delete the document(s) identified by the current query
[<CustomOperation "delete">]
member this.Delete (expr : ReqlExpr, opts : DeleteOptArg list) =
this.Delete expr |> DeleteOptArg.apply opts
// executing queries // executing queries
/// Execute the query, returning the result of the type specified /// Execute the query, returning the result of the type specified

View File

@ -47,13 +47,12 @@ let between (lowerKey : obj) (upperKey : obj) (expr : ReqlExpr) =
expr.Between (lowerKey, upperKey) expr.Between (lowerKey, upperKey)
/// Get document between a lower bound and an upper bound, specifying one or more optional arguments /// Get document between a lower bound and an upper bound, specifying one or more optional arguments
let betweenWithOptArgs (lowerKey : obj) (upperKey : obj) (args : (string * obj) seq) (expr : ReqlExpr) = let betweenWithOptArgs (lowerKey : obj) (upperKey : obj) args expr =
args between lowerKey upperKey expr |> BetweenOptArg.apply args
|> Seq.fold (fun (btw : Between) arg -> btw.OptArg (fst arg, snd arg)) (between lowerKey upperKey expr)
/// Get documents between a lower bound and an upper bound based on an index /// Get documents between a lower bound and an upper bound based on an index
let betweenIndex (lowerKey : obj) (upperKey : obj) (index : string) (expr : ReqlExpr) = let betweenIndex (lowerKey : obj) (upperKey : obj) index expr =
betweenWithOptArgs lowerKey upperKey [ "index", index ] expr betweenWithOptArgs lowerKey upperKey [ Index index ] expr
/// Get a connection builder that can be used to create one RethinkDB connection /// Get a connection builder that can be used to create one RethinkDB connection
let connection () = let connection () =
@ -61,7 +60,7 @@ let connection () =
/// Reference a database /// Reference a database
let db dbName = let db dbName =
r.Db dbName match dbName with "" -> r.Db () | _ -> r.Db dbName
/// Create a database /// Create a database
let dbCreate (dbName : string) = let dbCreate (dbName : string) =
@ -80,8 +79,8 @@ let delete (expr : ReqlExpr) =
expr.Delete () expr.Delete ()
/// Delete documents, providing optional arguments /// Delete documents, providing optional arguments
let deleteWithOptArgs (args : (string * obj) seq) expr = let deleteWithOptArgs args (expr : ReqlExpr) =
args |> Seq.fold (fun (del : Delete) arg -> del.OptArg (fst arg, snd arg)) (delete expr) delete expr |> DeleteOptArg.apply args
/// EqJoin the left field on the right-hand table using its primary key /// EqJoin the left field on the right-hand table using its primary key
let eqJoin (field : string) (table : Table) (expr : ReqlExpr) = let eqJoin (field : string) (table : Table) (expr : ReqlExpr) =
@ -111,50 +110,66 @@ let eqJoinJSIndex js table (indexName : string) expr =
let filter (filterSpec : obj) (expr : ReqlExpr) = let filter (filterSpec : obj) (expr : ReqlExpr) =
expr.Filter filterSpec expr.Filter filterSpec
/// Apply optional arguments to a filter /// Apply optional argument to a filter
let private optArgsFilter (args : (string * obj) seq) filter = let private optArgFilter arg (filter : Filter) =
args |> Seq.fold (fun (fil : Filter) arg -> fil.OptArg (fst arg, snd arg)) filter filter.OptArg (match arg with Default d -> d.reql)
/// Filter documents, providing optional arguments /// Filter documents, providing optional arguments
let filterWithOptArgs (filterSpec : obj) args expr = let filterWithOptArgs (filterSpec : obj) arg expr =
filter filterSpec expr |> optArgsFilter args filter filterSpec expr |> optArgFilter arg
/// Filter documents using a function /// Filter documents using a function
let filterFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) = let filterFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) =
expr.Filter (ReqlFunction1 (fun row -> f row :> obj)) expr.Filter (ReqlFunction1 (fun row -> f row :> obj))
/// Filter documents using a function, providing optional arguments /// Filter documents using a function, providing optional arguments
let filterFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr = let filterFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) arg expr =
filterFunc f expr |> optArgsFilter args filterFunc f expr |> optArgFilter arg
/// Filter documents using JavaScript /// Filter documents using JavaScript
let filterJS js (expr : ReqlExpr) = let filterJS js (expr : ReqlExpr) =
expr.Filter (toJS js) expr.Filter (toJS js)
/// Filter documents using JavaScript, providing optional arguments /// Filter documents using JavaScript, providing optional arguments
let filterJSWithOptArgs js args expr = let filterJSWithOptArgs js arg expr =
filterJS js expr |> optArgsFilter args filterJS js expr |> optArgFilter arg
/// Get a document by its primary key /// Get a document by its primary key
let get (documentId : obj) (table : Table) = let get (documentId : obj) (table : Table) =
table.Get documentId table.Get documentId
/// Get all documents matching primary keys
let getAll (ids : obj seq) (table : Table) =
table.GetAll (Array.ofSeq ids)
/// Get all documents matching keys in the given index /// Get all documents matching keys in the given index
let getAll (ids : obj seq) (indexName : string) (table : Table) = let getAllWithIndex (ids : obj seq) (indexName : string) table =
table.GetAll(Array.ofSeq ids).OptArg ("index", indexName) (getAll ids table).OptArg ("index", indexName)
/// Create an index on the given table /// Create an index on the given table
let indexCreate (indexName : string) (table : Table) = let indexCreate (indexName : string) (table : Table) =
table.IndexCreate indexName table.IndexCreate indexName
/// Create an index on the given table, including optional arguments
let indexCreateWithOptArgs (indexName : string) args (table : Table) =
indexCreate indexName table |> IndexCreateOptArg.apply args
/// Create an index on the given table using a function /// Create an index on the given table using a function
let indexCreateFunc<'T> (indexName : string) (f : ReqlExpr -> 'T) (table : Table) = let indexCreateFunc<'T> (indexName : string) (f : ReqlExpr -> 'T) (table : Table) =
table.IndexCreate (indexName, ReqlFunction1 (fun row -> f row :> obj)) table.IndexCreate (indexName, ReqlFunction1 (fun row -> f row :> obj))
/// Create an index on the given table using a function, including optional arguments
let indexCreateFuncWithOptArgs<'T> indexName (f : ReqlExpr -> 'T) args table =
indexCreateFunc indexName f table |> IndexCreateOptArg.apply args
/// Create an index on the given table using JavaScript /// Create an index on the given table using JavaScript
let indexCreateJS (indexName : string) js (table : Table) = let indexCreateJS (indexName : string) js (table : Table) =
table.IndexCreate (indexName, toJS js) table.IndexCreate (indexName, toJS js)
/// Create an index on the given table using JavaScript, including optional arguments
let indexCreateJSWithOptArgs indexName js args table =
indexCreateJS indexName js table |> IndexCreateOptArg.apply args
/// Drop an index /// Drop an index
let indexDrop (indexName : string) (table : Table) = let indexDrop (indexName : string) (table : Table) =
table.IndexDrop indexName table.IndexDrop indexName
@ -179,10 +194,6 @@ let innerJoinFunc<'T> (otherSeq : obj) (f : ReqlExpr -> ReqlExpr -> 'T) (expr :
let innerJoinJS (otherSeq : obj) js (expr : ReqlExpr) = let innerJoinJS (otherSeq : obj) js (expr : ReqlExpr) =
expr.InnerJoin (otherSeq, toJS js) expr.InnerJoin (otherSeq, toJS js)
/// Apply optional arguments to an insert
let private optArgsInsert (args : (string * obj) seq) ins =
args |> Seq.fold (fun (ins : Insert) arg -> ins.OptArg (fst arg, snd arg)) ins
/// Insert a single document (use insertMany for multiple) /// Insert a single document (use insertMany for multiple)
let insert<'T> (doc : 'T) (table : Table) = let insert<'T> (doc : 'T) (table : Table) =
table.Insert doc table.Insert doc
@ -193,11 +204,11 @@ let insertMany<'T> (docs : 'T seq) (table : Table) =
/// Insert a single document, providing optional arguments (use insertManyWithOptArgs for multiple) /// Insert a single document, providing optional arguments (use insertManyWithOptArgs for multiple)
let insertWithOptArgs<'T> (doc : 'T) args table = let insertWithOptArgs<'T> (doc : 'T) args table =
insert doc table |> optArgsInsert args insert doc table |> InsertOptArg.apply args
/// Insert multiple documents, providing optional arguments /// Insert multiple documents, providing optional arguments
let insertManyWithOptArgs<'T> (docs : 'T seq) args table = let insertManyWithOptArgs<'T> (docs : 'T seq) args table =
insertMany docs table |> optArgsInsert args insertMany docs table |> InsertOptArg.apply args
/// Test whether a sequence is empty /// Test whether a sequence is empty
let isEmpty (expr : ReqlExpr) = let isEmpty (expr : ReqlExpr) =
@ -223,17 +234,13 @@ let outerJoinJS (otherSeq : obj) js (expr : ReqlExpr) =
let pluck (fields : string seq) (expr : ReqlExpr) = let pluck (fields : string seq) (expr : ReqlExpr) =
expr.Pluck (Array.ofSeq fields) expr.Pluck (Array.ofSeq fields)
/// Apply optional arguments to a replace
let private optArgsReplace (args : (string * obj) seq) repl =
args |> Seq.fold (fun (rep : Replace) arg -> rep.OptArg (fst arg, snd arg)) repl
/// Replace documents /// Replace documents
let replace<'T> (replaceSpec : 'T) (expr : ReqlExpr) = let replace<'T> (replaceSpec : 'T) (expr : ReqlExpr) =
expr.Replace replaceSpec expr.Replace replaceSpec
/// Replace documents, providing optional arguments /// Replace documents, providing optional arguments
let replaceWithOptArgs<'T> (replaceSpec : 'T) args expr = let replaceWithOptArgs<'T> (replaceSpec : 'T) args expr =
replace replaceSpec expr |> optArgsReplace args replace replaceSpec expr |> ReplaceOptArg.apply args
/// Replace documents using a function /// Replace documents using a function
let replaceFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) = let replaceFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) =
@ -241,7 +248,7 @@ let replaceFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) =
/// Replace documents using a function, providing optional arguments /// Replace documents using a function, providing optional arguments
let replaceFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr = let replaceFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr =
replaceFunc f expr |> optArgsReplace args replaceFunc f expr |> ReplaceOptArg.apply args
/// Replace documents using JavaScript /// Replace documents using JavaScript
let replaceJS js (expr : ReqlExpr) = let replaceJS js (expr : ReqlExpr) =
@ -249,7 +256,7 @@ let replaceJS js (expr : ReqlExpr) =
/// Replace documents using JavaScript, providing optional arguments /// Replace documents using JavaScript, providing optional arguments
let replaceJSWithOptArgs js args expr = let replaceJSWithOptArgs js args expr =
replaceJS js expr |> optArgsReplace args replaceJS js expr |> ReplaceOptArg.apply args
/// Skip a number of elements from the head of a sequence /// Skip a number of elements from the head of a sequence
let skip n (expr : ReqlExpr) = let skip n (expr : ReqlExpr) =
@ -291,17 +298,13 @@ let tableList (db : Db) =
let tableListFromDefault () = let tableListFromDefault () =
r.TableList () r.TableList ()
/// Apply optional arguments to an update
let private optArgsUpdate (args : (string * obj) seq) upd =
args |> Seq.fold (fun (upd : Update) arg -> upd.OptArg (fst arg, snd arg)) upd
/// Update documents /// Update documents
let update<'T> (updateSpec : 'T) (expr : ReqlExpr) = let update<'T> (updateSpec : 'T) (expr : ReqlExpr) =
expr.Update updateSpec expr.Update updateSpec
/// Update documents, providing optional arguments /// Update documents, providing optional arguments
let updateWithOptArgs<'T> (updateSpec : 'T) args expr = let updateWithOptArgs<'T> (updateSpec : 'T) args expr =
update updateSpec expr |> optArgsUpdate args update updateSpec expr |> UpdateOptArg.apply args
/// Update documents using a function /// Update documents using a function
let updateFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) = let updateFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) =
@ -309,7 +312,7 @@ let updateFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) =
/// Update documents using a function, providing optional arguments /// Update documents using a function, providing optional arguments
let updateFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr = let updateFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr =
updateFunc f expr |> optArgsUpdate args updateFunc f expr |> UpdateOptArg.apply args
/// Update documents using JavaScript /// Update documents using JavaScript
let updateJS js (expr : ReqlExpr) = let updateJS js (expr : ReqlExpr) =
@ -317,7 +320,7 @@ let updateJS js (expr : ReqlExpr) =
/// Update documents using JavaScript, providing optional arguments /// Update documents using JavaScript, providing optional arguments
let updateJSWithOptArgs js args expr = let updateJSWithOptArgs js args expr =
updateJS js expr |> optArgsUpdate args updateJS js expr |> UpdateOptArg.apply args
/// Exclude fields from the result /// Exclude fields from the result
let without (columns : string seq) (expr : ReqlExpr) = let without (columns : string seq) (expr : ReqlExpr) =

View File

@ -0,0 +1,228 @@
namespace RethinkDb.Driver.FSharp
open RethinkDb.Driver
open RethinkDb.Driver.Ast
/// Delineates the type of bound when specifying bounded value ranges
type BoundType =
/// The bound includes the bounded value
| Open
/// The bound excludes the bounded value
| Closed
/// The string representation of this bound used in the ReQL query
member this.reql = match this with Open -> "open" | Closed -> "closed"
/// Optional arguments for the `between` statement
type BetweenOptArg =
/// Use the specified index
| Index of string
/// The lower bound type
| LowerBound of BoundType
/// The upper bound type
| UpperBound of BoundType
/// Function to support `between` optional arguments
module BetweenOptArg =
/// Apply a list of optional arguments to a between statement
let apply opts (b : Between) =
opts
|> List.fold (fun (btw : Between) arg ->
match arg with
| Index idx -> btw.OptArg ("index", idx)
| LowerBound typ -> btw.OptArg ("lower_bound", typ.reql)
| UpperBound typ -> btw.OptArg ("upper_bound", typ.reql))
b
/// The durability of a write command
type Durability =
/// Wait for write acknowledgement before returning
| Hard
/// Return before the write has been completely acknowledged
| Soft
/// The ReQL value of this argument
member this.reql = "durability", match this with Hard -> "hard" | Soft -> "soft"
/// Whether changes should be returned
type ReturnChanges =
/// Return all documents considered for change ("always")
| All
/// Return changes
| Changed
/// Do not return changes
| Nothing
/// The ReQL value of this argument
member this.reql = "return_changes", match this with All -> "always" :> obj | Changed -> true | Nothing -> false
/// Optional arguments for the `delete` statement
type DeleteOptArg =
/// The durability of the command
| Durability of Durability
/// Whether changes should be returned
| ReturnChanges of ReturnChanges
/// Whether write hooks should be ignored (assuming the user has the permission to ignore hooks)
| IgnoreWriteHook of bool
/// Function to support `delete` optional arguments
module DeleteOptArg =
/// Apply a list of optional arguments to a delete statement
let apply opts (d : Delete) =
opts
|> List.fold (fun (del : Delete) arg ->
match arg with
| Durability dur -> del.OptArg dur.reql
| ReturnChanges chg -> del.OptArg chg.reql
| IgnoreWriteHook ign -> del.OptArg ("ignore_write_hook", ign))
d
/// How a filter command should handle filtering on a field that does not exist
type FilterDefaultHandling =
/// Return documents where the filtered field is missing
| Return
/// Skip documents where the filtered field is missing
| Skip
/// Raise an error if the filtered field is missing from a document
| Error
/// The ReQL value for this default handling
member this.reql = "default", match this with Return -> true :> obj | Skip -> false | Error -> RethinkDB.R.Error ()
/// Optional arguments for the `filter` statement
type FilterOptArg =
| Default of FilterDefaultHandling
/// Function to support `filter` optional arguments
module FilterOptArg =
/// Apply an option argument to the filter statement
let apply arg (f : Filter) =
match arg with Default d -> f.OptArg d.reql
/// Optional arguments for the `indexCreate` statement
type IndexCreateOptArg =
/// Index multiple values in the given field
| Multi
/// Create a geospatial index
| Geospatial
/// The parameter for the ReQL OptArg call
member this.reql = (match this with Multi -> "multi" | Geospatial -> "geo"), true
/// Function to support `indexCreate` optional arguments
module IndexCreateOptArg =
/// Apply a list of optional arguments to an indexCreate statement
let apply (opts : IndexCreateOptArg list) (ic : IndexCreate) =
opts |> List.fold (fun (idxC : IndexCreate) arg -> idxC.OptArg arg.reql) ic
/// How to handle an insert conflict
type Conflict =
/// Return an error
| Error
/// Replace the existing document with the current one
| Replace
/// Update fields in the existing document with fields from the current one
| Update
/// Use a function to resolve conflicts
| Resolve of (ReqlExpr -> ReqlExpr -> ReqlExpr -> obj)
/// The ReQL for the conflict parameter
member this.reql =
let value : obj =
match this with
| Error -> "error"
| Replace -> "replace"
| Update -> "update"
| Resolve f -> ReqlFunction3 f :> obj
"conflict", value
/// Optional arguments for the `insert` statement
type InsertOptArg =
/// The durability of the command
| Durability of Durability
/// Whether changes should be returned
| ReturnChanges of ReturnChanges
/// How to handle conflicts
| OnConflict of Conflict
/// Whether write hooks should be ignored (assuming the user has the permission to ignore hooks)
| IgnoreWriteHook of bool
/// Function to support `insert` optional arguments
module InsertOptArg =
/// Apply a list of optional arguments to an insert statement
let apply (opts : InsertOptArg list) (i : Insert) =
opts
|> List.fold (fun (ins : Insert) arg ->
match arg with
| Durability dur -> ins.OptArg dur.reql
| ReturnChanges chg -> ins.OptArg chg.reql
| OnConflict con -> ins.OptArg con.reql
| IgnoreWriteHook ign -> ins.OptArg ("ignore_write_hook", ign))
i
/// Optional arguments for the `replace` statement
type ReplaceOptArg =
/// The durability of the command
| Durability of Durability
/// Whether changes should be returned
| ReturnChanges of ReturnChanges
/// Allow the command to succeed if it is non-deterministic
| NonAtomic of bool
/// Whether write hooks should be ignored (assuming the user has the permission to ignore hooks)
| IgnoreWriteHook of bool
/// Function to support `replace` optional arguments
module ReplaceOptArg =
/// Apply a list of optional arguments to a replace statement
let apply opts (r : Replace) =
opts
|> List.fold (fun (rep : Replace) arg ->
match arg with
| Durability dur -> rep.OptArg dur.reql
| ReturnChanges chg -> rep.OptArg chg.reql
| NonAtomic non -> rep.OptArg ("non_atomic", non)
| IgnoreWriteHook ign -> rep.OptArg ("ignore_write_hook", ign))
r
/// Optional arguments for the `update` statement
type UpdateOptArg =
/// The durability of the command
| Durability of Durability
/// Whether changes should be returned
| ReturnChanges of ReturnChanges
/// Allow the command to succeed if it is non-deterministic
| NonAtomic of bool
/// Whether write hooks should be ignored (assuming the user has the permission to ignore hooks)
| IgnoreWriteHook of bool
/// Function to support `update` optional arguments
module UpdateOptArg =
/// Apply a list of optional arguments to an update statement
let apply opts (u : Update) =
opts
|> List.fold (fun (upd : Update) arg ->
match arg with
| Durability dur -> upd.OptArg dur.reql
| ReturnChanges chg -> upd.OptArg chg.reql
| NonAtomic non -> upd.OptArg ("non_atomic", non)
| IgnoreWriteHook ign -> upd.OptArg ("ignore_write_hook", ign))
u

View File

@ -12,11 +12,12 @@
<Copyright>See LICENSE</Copyright> <Copyright>See LICENSE</Copyright>
<PackageTags>RethinkDB document F#</PackageTags> <PackageTags>RethinkDB document F#</PackageTags>
<VersionPrefix>0.8.0</VersionPrefix> <VersionPrefix>0.8.0</VersionPrefix>
<VersionSuffix>alpha-0001</VersionSuffix> <VersionSuffix>alpha-0002</VersionSuffix>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Retry.fs" /> <Compile Include="Retry.fs" />
<Compile Include="OptArgs.fs" />
<Compile Include="Builder.fs" /> <Compile Include="Builder.fs" />
<Compile Include="Functions.fs" /> <Compile Include="Functions.fs" />
<Compile Include="Config.fs" /> <Compile Include="Config.fs" />