-
Notifications
You must be signed in to change notification settings - Fork 9
Code Quotations Spec
Intend to support all selectors and operators listed here in one form or another.
let (?) (doc : BsonDocument) (field : string) =
unbox doc.[field]
let (?<-) (doc : BsonDocument) (field : string) value =
doc.[field] = unbox value |> ignore
module Query =
let all (x : 'a list) (y : 'a list) : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> x?tags |> Query.all [ "appliances"; "school"; "book" ] @>
There is no actual $eq
operator, but you get the idea...
bson <@ fun (x : BsonDocument) -> x?qty = 20 @>
bson <@ fun (x : BsonDocument) -> x?qty > 20 @>
bson <@ fun (x : BsonDocument) -> x?qty >= 20 @>
Decided to add single-quote after identifier to avoid name conflict.
module Query =
let in' (x : 'a list) (y : 'a) : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> x?qty |> Query.in' [ 5; 15 ] @>
bson <@ fun (x : BsonDocument) -> x?qty < 20 @>
bson <@ fun (x : BsonDocument) -> x?qty <= 20 @>
bson <@ fun (x : BsonDocument) -> x?qty <> 20 @>
module Query =
let nin (x : 'a list) (y : 'a) : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> x?qty |> Query.nin [ 5; 15 ] @>
bson <@ fun x -> x?price = 1.99 && (x?qty < 20 || x?sale = true) @>
bson <@ fun x -> x?price = 1.99 && x?qty < 20 && x?sale = true @>
bson <@ fun x -> not (x?price > 1.99) @>
module Query =
let nor (x : bool list) : bool = invalidOp "not implemented"
bson <@ fun x -> Query.nor [ x?price = 1.99; x?qty < 20; x?sale = true ] @>
Could define a pair of functions n/exists
, or use a similar semantic of { $exists: <bool> }
.
module Query =
let exists x : bool = invalidOp "not implemented"
let nexists x : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> x?qty |> Query.exists && x?qty |> Query.nin [ 5; 15 ] @>
bson <@ fun (x : BsonDocument) -> x?qty |> Query.nexists || x?qty |> Query.in [ 5; 15 ] @>
bson <@ fun (x : BsonDocument) -> x?qty % 4 = 0 @>
All BsonValue
instances have a BsonType
property, which could be used to perform the check with regard to an enum (that has meaningful names). Doing so requires an explicit upcast, however.
bson <@ fun (x : BsonDocument) -> (x?price :> BsonValue).BsonType = BsonType.Double @>
The alternative is to define a function that would take an integer or type.
module Query =
let type' (x : BsonType) y : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> x?price |> Query.type' BsonType.Double @>
module Query =
let where (x : string) y : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> x |> Query.where "this.credits == this.debits" @>
let (=~) input pattern =
System.Text.RegularExpressions.Regex.IsMatch(input, pattern)
bson <@ fun (x : BsonDocument) -> x?desc?short =~ "/acme.*corp/i" @>
module Query =
let elemMatch x y : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) ->
x?sizes |> Query.elemMatch (bson <@ fun (y : BsonDocument) -> y?length = 1 && y?width > 1 @>) @>
module Query =
let size (x : int) y : bool = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> x?tags |> Query.size 2 @>
Since the update command is able to affect multiple fields with different operations, the return type of the function should be a unit list
rather than a bool
.
bson <@ fun (x : BsonDocument) -> [ x?qty <- (+) 1 ] @>
bson <@ fun (x : BsonDocument) -> [ x?qty <- (-) 2 ] @>
module Update =
let rename (x : (string * string) list) (y : 'a) : 'a = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x |> Update.rename [ ("nickname", "alias"); ("cell", "mobile") ] |> ignore ] @>
module Update =
let setOnInsert (x : unit list) (y : 'a) : 'a = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x |> Update.setOnInsert [ x?defaultQty <- 100 ] |> ignore ] @>
Should we also use an option type here, i.e. Some x
, to parallel the $unset
operator?
bson <@ fun (x : BsonDocument) -> [ x?qty <- 10 ] @>
bson <@ fun (x : BsonDocument) -> [ x?option <- None ] @>
bson <@ fun (x : BsonDocument) -> [ x ? grades ? ``$`` <- 82 ] @>
module Update =
let addToSet (x : 'a) (y : 'a list) : 'a list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?tags <- Update.addToSet "toaster" ] @>
Could define as two separate operators: popleft
and popright
, or use a similar semantic of { $pop: { field: +/- 1 } }
.
module Update =
let popleft (x : 'a list) : 'a list = invalidOp "not implemented"
let popright (x : 'a list) : 'a list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?sizes <- Update.popleft ] @>
bson <@ fun (x : BsonDocument) -> [ x?sizes <- Update.popright ] @>
module Update =
let pull (x : 'a) (y : 'b list) : 'b list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?sizes <- Update.pull (bson <@ fun (y : BsonDocument) -> y?height = 75 @>) ] @>
module Update =
let pullAll (x : 'a list) (y : 'a list) : 'a list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?tags <- Update.pullAll [ "appliances"; "school"; "book" ] ] @>
module Update =
let push (x : 'a) (y : 'a list) : 'a list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?tags <- Update.push "toaster" ] @>
module Update =
let each (x : 'a -> 'a list -> 'a list) (y : 'a list) (z : 'a list) : 'a list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?tags <- Update.each Update.addToSet [ "appliances"; "school"; "book" ] ] @>
bson <@ fun (x : BsonDocument) -> [ x?tags <- Update.each Update.push [ "appliances"; "school"; "book" ] ] @>
module Update =
let slice (x : int) (y : 'a list) : 'a list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?tags <- Update.each Update.push [ "appliances"; "school"; "book" ]
>> Update.slice -5 ] @>
module Update =
let sort (x : 'a) (y : 'b list) : 'b list = invalidOp "not implemented"
bson <@ fun (x : BsonDocument) -> [ x?sizes <- Update.each Update.push [ { length = 3; width = 8; height = 1 }
{ length = 4; width = 7; height = 2 }
{ length = 5; width = 6; height = 4 } ]
>> Update.sort (bson <@ fun (y : BsonDocument) -> y?width = 1 @>)
>> Update.slice -5 } @>
bson <@ fun (x : BsonDocument) -> [ x?qty <- (&&&) 5 ] @>
bson <@ fun (x : BsonDocument) -> [ x?qty <- (|||) 5 ] @>