From eab4cb80b0e97505d95ff87f3c885065c7e339ff Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Tue, 19 Apr 2022 10:38:29 -0400 Subject: [PATCH] Add strongly-typed opt args - Add between to CE - Return default db from calls if name is blank --- src/RethinkDb.Driver.FSharp/Builder.fs | 142 ++++++++--- src/RethinkDb.Driver.FSharp/Functions.fs | 81 ++++--- src/RethinkDb.Driver.FSharp/OptArgs.fs | 228 ++++++++++++++++++ .../RethinkDb.Driver.FSharp.fsproj | 3 +- 4 files changed, 374 insertions(+), 80 deletions(-) create mode 100644 src/RethinkDb.Driver.FSharp/OptArgs.fs diff --git a/src/RethinkDb.Driver.FSharp/Builder.fs b/src/RethinkDb.Driver.FSharp/Builder.fs index dfc34c4..5541bd8 100644 --- a/src/RethinkDb.Driver.FSharp/Builder.fs +++ b/src/RethinkDb.Driver.FSharp/Builder.fs @@ -3,17 +3,10 @@ module RethinkDb.Driver.FSharp.RethinkBuilder open RethinkDb.Driver open RethinkDb.Driver.Ast +open RethinkDb.Driver.FSharp open RethinkDb.Driver.Net 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 type RethinkBuilder<'T> () = @@ -31,6 +24,25 @@ type RethinkBuilder<'T> () = member _.Yield _ = RethinkDB.R + // database/table identification + + /// Specify a database for further commands + [] + member _.Db (expr : RethinkDB, db : string) = match db with "" -> expr.Db () | _ -> expr.Db db + + /// Specify a table in the default database + [] + member _.TableInDefaultDb (expr : RethinkDB, table : string) = expr.Table table + + /// Specify a table in a specific database + [] + member _.Table (db : Db, table : string) = db.Table table + + /// Create an equality join with another table + [] + member _.EqJoin (expr : ReqlExpr, field : string, otherTable : string) = + expr.EqJoin (field, RethinkDB.R.Table otherTable) + // meta queries (tables, indexes, etc.) /// List all databases @@ -46,16 +58,16 @@ type RethinkBuilder<'T> () = member _.TableList (r : RethinkDB) = r.TableList () /// List all tables for the specified database - [] - 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 [] member _.TableCreate (r : RethinkDB, table : string) = r.TableCreate table /// Create a table in the default database - [] - 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 [] @@ -65,44 +77,35 @@ type RethinkBuilder<'T> () = [] member _.IndexCreate (tbl : Table, index : string) = tbl.IndexCreate index + /// Create an index for a table, specifying an optional argument + [] + 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 [] member _.IndexCreate (tbl : Table, index : string, f : ReqlExpr -> obj) = tbl.IndexCreate (index, ReqlFunction1 f) - /// Specify options for certain types of indexes - [] - member _.IndexOption (idx : IndexCreate, opt : IndexOption) = - idx.OptArg ((match opt with Multi -> "multi" | Geospatial -> "geo"), true) - - // database/table identification - - /// Specify a database for further commands - [] - member _.Db (expr : RethinkDB, db : string) = expr.Db db - - /// Specify a table in the default database - [] - member _.TableInDefaultDb (expr : RethinkDB, table : string) = expr.Table table - - /// Specify a table in a specific database - [] - member _.Table (expr : RethinkDB, table : string, db : string) = expr.Db(db).Table table - - /// Create an equality join with another table - [] - member _.EqJoin (expr : ReqlExpr, field : string, otherTable : string) = - expr.EqJoin (field, RethinkDB.R.Table otherTable) - + /// Create an index for a table, using a function to calculate the index + [] + member this.IndexCreate (tbl : Table, index : string, f : ReqlExpr -> obj, opts : IndexCreateOptArg list) = + this.IndexCreate (tbl, index, f) |> IndexCreateOptArg.apply opts + // data retrieval / manipulation /// Get a document from a table by its ID [] member _.Get (tbl : Table, key : obj) = tbl.Get key + /// Get all documents matching the given primary key value + [] + member _.GetAll (tbl : Table, keys : obj list) = + tbl.GetAll (Array.ofList keys) + /// Get all documents matching the given index value [] - member _.GetAll (tbl : Table, keys : obj list, index : string) = - tbl.GetAll(Array.ofList keys).OptArg ("index", index) + member this.GetAll (tbl : Table, keys : obj list, index : string) = + this.GetAll(tbl, keys).OptArg ("index", index) /// Skip a certain number of results [] @@ -120,19 +123,58 @@ type RethinkBuilder<'T> () = [] 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 + [] + 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 [] member _.Filter (expr : ReqlExpr, filter : (string * obj) list) = expr.Filter (fieldsToMap filter) + /// Filter a query by multiple field values, including an optional argument + [] + member this.Filter (expr : ReqlExpr, filter : (string * obj) list, opt : FilterOptArg) = + this.Filter (expr, filter) |> FilterOptArg.apply opt + /// Filter a query by a function [] member _.Filter (expr : ReqlExpr, f : ReqlExpr -> obj) = expr.Filter (ReqlFunction1 f) + /// Filter a query by a function, including an optional argument + [] + 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) [] - member _.Filter (expr : ReqlExpr, fs : (ReqlExpr -> obj) list) = - fs |> List.fold (fun (e : ReqlExpr) f -> e.Filter (ReqlFunction1 f)) expr + member _.Filter (expr : ReqlExpr, fs : (ReqlExpr -> obj) list) : Filter = + (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 + [] + 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 + [] + member _.Filter (expr : ReqlExpr, js : string) = expr.Filter (Javascript js) + + /// Filter a query using a JavaScript expression, including an optional argument + [] + member this.Filter (expr : ReqlExpr, js : string, opt : FilterOptArg) = + this.Filter (expr, js) |> FilterOptArg.apply opt + + /// Filter a query by a range of values + [] + member _.Between (expr : ReqlExpr, lower : obj, upper : obj) = + expr.Between (lower, upper) + + /// Filter a query by a range of values, using optional arguments + [] + 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 [] member _.Map (expr : ReqlExpr, f : ReqlExpr -> obj) = expr.Map (ReqlFunction1 f) @@ -169,18 +211,38 @@ type RethinkBuilder<'T> () = [] member _.Insert (tbl : Table, doc : obj) = tbl.Insert doc + /// Insert a document into the given table, using optional arguments + [] + member this.Insert (tbl : Table, doc : obj, opts : InsertOptArg list) = + this.Insert (tbl, doc) |> InsertOptArg.apply opts + /// Update specific fields in a document [] member _.Update (expr : ReqlExpr, fields : (string * obj) list) = expr.Update (fieldsToMap fields) + /// Update specific fields in a document, using optional arguments + [] + 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 [] member _.Replace (expr : ReqlExpr, doc : obj) = expr.Replace doc + /// Replace the current query with the specified document, using optional arguments + [] + 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 [] member _.Delete (expr : ReqlExpr) = expr.Delete () + /// Delete the document(s) identified by the current query + [] + member this.Delete (expr : ReqlExpr, opts : DeleteOptArg list) = + this.Delete expr |> DeleteOptArg.apply opts + // executing queries /// Execute the query, returning the result of the type specified diff --git a/src/RethinkDb.Driver.FSharp/Functions.fs b/src/RethinkDb.Driver.FSharp/Functions.fs index a6224f8..46e04cd 100644 --- a/src/RethinkDb.Driver.FSharp/Functions.fs +++ b/src/RethinkDb.Driver.FSharp/Functions.fs @@ -47,13 +47,12 @@ let between (lowerKey : obj) (upperKey : obj) (expr : ReqlExpr) = expr.Between (lowerKey, upperKey) /// 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) = - args - |> Seq.fold (fun (btw : Between) arg -> btw.OptArg (fst arg, snd arg)) (between lowerKey upperKey expr) +let betweenWithOptArgs (lowerKey : obj) (upperKey : obj) args expr = + between lowerKey upperKey expr |> BetweenOptArg.apply args /// Get documents between a lower bound and an upper bound based on an index -let betweenIndex (lowerKey : obj) (upperKey : obj) (index : string) (expr : ReqlExpr) = - betweenWithOptArgs lowerKey upperKey [ "index", index ] expr +let betweenIndex (lowerKey : obj) (upperKey : obj) index expr = + betweenWithOptArgs lowerKey upperKey [ Index index ] expr /// Get a connection builder that can be used to create one RethinkDB connection let connection () = @@ -61,7 +60,7 @@ let connection () = /// Reference a database let db dbName = - r.Db dbName + match dbName with "" -> r.Db () | _ -> r.Db dbName /// Create a database let dbCreate (dbName : string) = @@ -80,8 +79,8 @@ let delete (expr : ReqlExpr) = expr.Delete () /// Delete documents, providing optional arguments -let deleteWithOptArgs (args : (string * obj) seq) expr = - args |> Seq.fold (fun (del : Delete) arg -> del.OptArg (fst arg, snd arg)) (delete expr) +let deleteWithOptArgs args (expr : ReqlExpr) = + delete expr |> DeleteOptArg.apply args /// EqJoin the left field on the right-hand table using its primary key 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) = expr.Filter filterSpec -/// Apply optional arguments to a filter -let private optArgsFilter (args : (string * obj) seq) filter = - args |> Seq.fold (fun (fil : Filter) arg -> fil.OptArg (fst arg, snd arg)) filter +/// Apply optional argument to a filter +let private optArgFilter arg (filter : Filter) = + filter.OptArg (match arg with Default d -> d.reql) /// Filter documents, providing optional arguments -let filterWithOptArgs (filterSpec : obj) args expr = - filter filterSpec expr |> optArgsFilter args +let filterWithOptArgs (filterSpec : obj) arg expr = + filter filterSpec expr |> optArgFilter arg /// Filter documents using a function let filterFunc<'T> (f : ReqlExpr -> 'T) (expr : ReqlExpr) = expr.Filter (ReqlFunction1 (fun row -> f row :> obj)) /// Filter documents using a function, providing optional arguments -let filterFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr = - filterFunc f expr |> optArgsFilter args +let filterFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) arg expr = + filterFunc f expr |> optArgFilter arg /// Filter documents using JavaScript let filterJS js (expr : ReqlExpr) = expr.Filter (toJS js) /// Filter documents using JavaScript, providing optional arguments -let filterJSWithOptArgs js args expr = - filterJS js expr |> optArgsFilter args +let filterJSWithOptArgs js arg expr = + filterJS js expr |> optArgFilter arg /// Get a document by its primary key let get (documentId : obj) (table : Table) = 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 -let getAll (ids : obj seq) (indexName : string) (table : Table) = - table.GetAll(Array.ofSeq ids).OptArg ("index", indexName) +let getAllWithIndex (ids : obj seq) (indexName : string) table = + (getAll ids table).OptArg ("index", indexName) /// Create an index on the given table let indexCreate (indexName : string) (table : Table) = 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 let indexCreateFunc<'T> (indexName : string) (f : ReqlExpr -> 'T) (table : Table) = 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 let indexCreateJS (indexName : string) js (table : Table) = 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 let indexDrop (indexName : string) (table : Table) = table.IndexDrop indexName @@ -179,10 +194,6 @@ let innerJoinFunc<'T> (otherSeq : obj) (f : ReqlExpr -> ReqlExpr -> 'T) (expr : let innerJoinJS (otherSeq : obj) js (expr : ReqlExpr) = 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) let insert<'T> (doc : 'T) (table : Table) = 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) let insertWithOptArgs<'T> (doc : 'T) args table = - insert doc table |> optArgsInsert args + insert doc table |> InsertOptArg.apply args /// Insert multiple documents, providing optional arguments 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 let isEmpty (expr : ReqlExpr) = @@ -223,17 +234,13 @@ let outerJoinJS (otherSeq : obj) js (expr : ReqlExpr) = let pluck (fields : string seq) (expr : ReqlExpr) = 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 let replace<'T> (replaceSpec : 'T) (expr : ReqlExpr) = expr.Replace replaceSpec /// Replace documents, providing optional arguments let replaceWithOptArgs<'T> (replaceSpec : 'T) args expr = - replace replaceSpec expr |> optArgsReplace args + replace replaceSpec expr |> ReplaceOptArg.apply args /// Replace documents using a function 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 let replaceFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr = - replaceFunc f expr |> optArgsReplace args + replaceFunc f expr |> ReplaceOptArg.apply args /// Replace documents using JavaScript let replaceJS js (expr : ReqlExpr) = @@ -249,7 +256,7 @@ let replaceJS js (expr : ReqlExpr) = /// Replace documents using JavaScript, providing optional arguments 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 let skip n (expr : ReqlExpr) = @@ -291,17 +298,13 @@ let tableList (db : Db) = let tableListFromDefault () = 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 let update<'T> (updateSpec : 'T) (expr : ReqlExpr) = expr.Update updateSpec /// Update documents, providing optional arguments let updateWithOptArgs<'T> (updateSpec : 'T) args expr = - update updateSpec expr |> optArgsUpdate args + update updateSpec expr |> UpdateOptArg.apply args /// Update documents using a function 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 let updateFuncWithOptArgs<'T> (f : ReqlExpr -> 'T) args expr = - updateFunc f expr |> optArgsUpdate args + updateFunc f expr |> UpdateOptArg.apply args /// Update documents using JavaScript let updateJS js (expr : ReqlExpr) = @@ -317,7 +320,7 @@ let updateJS js (expr : ReqlExpr) = /// Update documents using JavaScript, providing optional arguments let updateJSWithOptArgs js args expr = - updateJS js expr |> optArgsUpdate args + updateJS js expr |> UpdateOptArg.apply args /// Exclude fields from the result let without (columns : string seq) (expr : ReqlExpr) = diff --git a/src/RethinkDb.Driver.FSharp/OptArgs.fs b/src/RethinkDb.Driver.FSharp/OptArgs.fs new file mode 100644 index 0000000..7445c74 --- /dev/null +++ b/src/RethinkDb.Driver.FSharp/OptArgs.fs @@ -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 + diff --git a/src/RethinkDb.Driver.FSharp/RethinkDb.Driver.FSharp.fsproj b/src/RethinkDb.Driver.FSharp/RethinkDb.Driver.FSharp.fsproj index 18962e0..f3fc722 100644 --- a/src/RethinkDb.Driver.FSharp/RethinkDb.Driver.FSharp.fsproj +++ b/src/RethinkDb.Driver.FSharp/RethinkDb.Driver.FSharp.fsproj @@ -12,11 +12,12 @@ See LICENSE RethinkDB document F# 0.8.0 - alpha-0001 + alpha-0002 +