Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[feature] stdlib: Added mapReduce and assertions to error handling.

  • Loading branch information...
commit aba9ac7676552c20f11a2e8754146493b3a2aab5 1 parent 3017fcf
@nrs135 nrs135 authored
View
27 stdlib/apis/mongo/bson.opa
@@ -116,6 +116,8 @@ type Bson.error = {
ok: Bson.register(Bson.int32);
err: Bson.register(string);
code: Bson.register(Bson.int32);
+ assertion: Bson.register(string);
+ assertionCode: Bson.register(Bson.int32);
n: Bson.register(Bson.int32);
errmsg: Bson.register(string);
}
@@ -498,10 +500,20 @@ Bson = {{
code = match find_int(doc, "code") with | {some=code} -> "<code={code}>" | {none} -> ""
n = match find_int(doc, "n") with | {some=n} -> "<n={n}>" | {none} -> ""
errmsg = match find_string(doc, "errmsg") with | {some=""} -> "" | {some=errmsg} -> "<errmsg=\"{errmsg}\">" | {none} -> ""
- String.concat(" ",List.filter((s -> s != ""),[ok,err,code,n,errmsg]))
+ assertion =
+ match find_string(doc, "assertion") with
+ | {some=""} -> ""
+ | {some=assertion} -> "<assertion=\"{assertion}\">"
+ | {none} -> ""
+ assertionCode =
+ match find_int(doc, "assertionCode") with
+ | {some=assertionCode} -> "<assertionCode={assertionCode}>"
+ | {none} -> ""
+ String.concat(" ",List.filter((s -> s != ""),[ok,err,code,n,errmsg,assertion,assertionCode]))
/**
* Decide if a document contains an error or not.
+ * Note, we don't need to check for assertions because we always get an errmsg in that case.
**/
is_error(doc:Bson.document): bool =
(match find_int(doc,"ok") with {some=ok} -> ok != 1 | {none} -> false) ||
@@ -530,9 +542,12 @@ Bson = {{
| {absent} -> "<unknown ok status>"
err = match error.err with | {present=""} -> "" | {present=err} -> "<err=\"{err}\">" | {absent} -> ""
code = match error.code with | {present=code} -> "<code={code}>" | {absent} -> ""
+ assertion =
+ match error.assertion with | {present=""} -> "" | {present=assertion} -> "<assertion=\"{assertion}\">" | {absent} -> ""
+ assertionCode = match error.assertionCode with | {present=assertionCode} -> "<assertionCode={assertionCode}>" | {absent} -> ""
n = match error.n with | {present=n} -> "<n={n}>" | {absent} -> ""
errmsg = match error.errmsg with | {present=""} -> "" | {present=errmsg} -> "<errmsg=\"{errmsg}\">" | {absent} -> ""
- String.concat(" ",List.filter((s -> s != ""),[ok,err,code,n,errmsg]))
+ String.concat(" ",List.filter((s -> s != ""),[ok,err,code,assertion,assertionCode,n,errmsg]))
/**
* We can't always use [bson_to_opa] to extract the error-relevant
@@ -554,6 +569,14 @@ Bson = {{
match find_int(doc,"code") with
| {some=code} -> {present=code}
| {none} -> {absent};
+ assertion=
+ match find_string(doc, "assertion") with
+ | {some=assertion} -> {present=assertion}
+ | {none} -> {absent};
+ assertionCode=
+ match find_int(doc,"assertionCode") with
+ | {some=assertionCode} -> {present=assertionCode}
+ | {none} -> {absent};
n=
match find_int(doc,"n") with
| {some=n} -> {present=n}
View
46 stdlib/apis/mongo/commands.opa
@@ -167,6 +167,10 @@ type Mongo.explainType =
// oldPlan: ... sometimes present
}
+type Mongo.string_or_document =
+ {string : string}
+ / {document : Bson.document}
+
@server_private
MongoCommands = {{
@@ -466,7 +470,8 @@ MongoCommands = {{
* Set chunksize in MB.
**/
setChunkSize(m:Mongo.mongodb, size:int): bool =
- MongoDriver.update(m.mongo,MongoCommon.UpsertBit,"config.settings",[H.str("_id","chunksize")],[H.doc("$set",[H.i32("value",size)])])
+ MongoDriver.update(m.mongo,MongoCommon.UpsertBit,"config.settings",
+ [H.str("_id","chunksize")],[H.doc("$set",[H.i32("value",size)])])
/**
* Query the "config.chunks" database, gives a information about shard distribution.
@@ -534,7 +539,7 @@ MongoCommands = {{
*
* {b Warning, moving a large chunk might take a little time.}
*
- * Example: [reallyRemoveShard(m, db, shard, retryTime, maxRetries)]
+ * Example: [reallyRemoveShard(m, shard, retryTime, maxRetries)]
**/
reallyRemoveShard(m:Mongo.mongodb, shard:string, retryTime:int, maxRetries:int): Mongo.result =
rec aux(time,retries) =
@@ -711,6 +716,43 @@ MongoCommands = {{
findAndRemoveOpa(m,dbname,collection,query,remove,new_opt,sort_opt) =
MongoCommon.resultToOpa(findAndRemove(m,dbname,collection,query,remove,new_opt,sort_opt))
+ /**
+ * A bare no-frills mapReduce function. We ask for all of the options, including
+ * the complicated "out" option and we do minimal processing on the result, basically
+ * if [ok] is "1" then we return the entire reply as a success, otherwise we return
+ * the whole document as a failure. Some processing on the options and results may
+ * be added later.
+ **/
+ mapReduce(m:Mongo.mongodb, map:string, reduce:string,
+ query_opt:option(Bson.document),
+ sort_opt:option(Bson.document),
+ limit_opt:option(int),
+ out_opt:option(Mongo.string_or_document),
+ keeptemp_opt:option(bool),
+ finalize_opt:option(string),
+ scope_opt:option(Bson.document),
+ jsMode_opt:option(bool),
+ verbose_opt:option(bool)): Mongo.result =
+ cmd = List.flatten([[H.str("mapReduce",m.collection), H.code("map",map), H.code("reduce",reduce) ],
+ (match query_opt with | {some=query} -> [H.doc("query",query)] | {none} -> []),
+ (match sort_opt with | {some=sort} -> [H.doc("sort",sort)] | {none} -> []),
+ (match limit_opt with | {some=limit} -> [H.i32("limit",limit)] | {none} -> []),
+ (match out_opt with
+ | {some={string=out}} -> [H.str("out",out)]
+ | {some={document=out}} -> [H.doc("out",out)]
+ | {none} -> []),
+ (match keeptemp_opt with | {some=keeptemp} -> [H.bool("keeptemp",keeptemp)] | {none} -> []),
+ (match finalize_opt with | {some=finalize} -> [H.code("finalize",finalize)] | {none} -> []),
+ (match scope_opt with | {some=scope} -> [H.doc("scope",scope)] | {none} -> []),
+ (match jsMode_opt with | {some=jsMode} -> [H.bool("jsMode",jsMode)] | {none} -> []),
+ (match verbose_opt with | {some=verbose} -> [H.bool("verbose",verbose)] | {none} -> [])])
+ match run_command(m, m.dbname, cmd) with
+ | {success=doc} ->
+ if (match Bson.find_int(doc,"ok") with | {some=ok} -> ok == 1 | {none} -> false)
+ then {success=doc}
+ else {failure={DocError=doc}}
+ | {~failure} -> {~failure}
+
@private pass_digest(user:string, pass:string): string = Crypto.Hash.md5("{user}:mongo:{pass}")
/**
View
15 stdlib/apis/mongo/common.opa
@@ -198,19 +198,16 @@ MongoCommon = {{
/**
* Validate a BSON document by turning it into a [Mongo.result] value.
- * If [ok] is not 1 or there is an [errmsg] value then turn it into a [Mongo.failure] value.
+ * If [ok] is not 1 then turn it into a [Mongo.failure] value.
* Note that if there is no "ok" element then we assume success.
**/
- check_ok(bson:Bson.document): Mongo.result =
- match Bson.find_int(bson,"ok") with
+ check_ok(doc:Bson.document): Mongo.result =
+ match Bson.find_int(doc,"ok") with
| {some=ok} ->
if ok == 1
- then {success=bson}
- else
- (match Bson.find_string(bson,"errmsg") with
- | {some=errmsg} -> failErr(errmsg)
- | _ -> failErr("ok:{ok}"))
- | _ -> {success=bson}
+ then {success=doc}
+ else {failure={DocError=doc}}
+ | _ -> {success=doc}
/**
* Outcome-wrapped versions of Bson.find_xxx etc.
Please sign in to comment.
Something went wrong with that request. Please try again.