Skip to content

Commit

Permalink
[enhance] stdlib: Added errno handling, updated option names, added e…
Browse files Browse the repository at this point in the history
…val function, added insert_result etc.
  • Loading branch information
nrs135 committed Nov 24, 2011
1 parent cc4c0eb commit 7c8a675
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 31 deletions.
15 changes: 13 additions & 2 deletions stdlib/apis/mongo/bson.opa
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type Bson.error = {
ok: Bson.register(Bson.int32);
err: Bson.register(string);
code: Bson.register(Bson.int32);
errno: Bson.register(Bson.int32);
assertion: Bson.register(string);
assertionCode: Bson.register(Bson.int32);
n: Bson.register(Bson.int32);
Expand Down Expand Up @@ -158,6 +159,8 @@ Bson = {{
arr(n:string,d:Bson.document):Bson.element = {name=n; value={Array=d}}
docarr(n:string,l:list(Bson.document)):Bson.element =
{name=n; value={Array=List.mapi((i, d -> ({name="{i}"; value={Document=d}}:Bson.element)),l)}}
valarr(n:string,l:list(Bson.value)):Bson.element =
{name=n; value={Array=List.mapi((i, value -> ({name="{i}"; ~value}:Bson.element)),l)}}
binary(n:string,b:Bson.binary):Bson.element = {name=n; value={Binary=b}}
oid(n:string,id:string):Bson.element = {name=n; value={ObjectID=id}}
bool(n:string,b:bool):Bson.element = {name=n; value={Boolean=b}}
Expand Down Expand Up @@ -498,6 +501,7 @@ Bson = {{
| {none} -> "<unknown ok status>"
err = match find_string(doc, "err") with | {some=""} -> "" | {some=err} -> "<err=\"{err}\">" | {none} -> ""
code = match find_int(doc, "code") with | {some=code} -> "<code={code}>" | {none} -> ""
errno = match find_int(doc, "errno") with | {some=errno} -> "<errno={errno}>" | {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} -> ""
assertion =
Expand All @@ -509,7 +513,7 @@ Bson = {{
match find_int(doc, "assertionCode") with
| {some=assertionCode} -> "<assertionCode={assertionCode}>"
| {none} -> ""
String.concat(" ",List.filter((s -> s != ""),[ok,err,code,n,errmsg,assertion,assertionCode]))
String.concat(" ",List.filter((s -> s != ""),[ok,err,code,errno,n,errmsg,assertion,assertionCode]))
/**
* Decide if a document contains an error or not.
Expand All @@ -519,6 +523,7 @@ Bson = {{
(match find_int(doc,"ok") with {some=ok} -> ok != 1 | {none} -> false) ||
(match find_string(doc, "err") with {some=err} -> err != "" | {none} -> false) ||
(match find_int(doc, "code") with {some=code} -> code != 0 | {none} -> false) ||
(match find_int(doc, "errno") with {some=errno} -> errno != 0 | {none} -> false) ||
(match find_string(doc, "errmsg") with {some=errmsg} -> errmsg != "" | {none} -> false)
/**
Expand All @@ -528,6 +533,7 @@ Bson = {{
(match err.ok with {present=ok} -> ok != 1 | {absent} -> false) ||
(match err.err with {present=err} -> err != "" | {absent} -> false) ||
(match err.code with {present=code} -> code != 0 | {absent} -> false) ||
(match err.errno with {present=errno} -> errno != 0 | {absent} -> false) ||
(match err.errmsg with {present=errmsg} -> errmsg != "" | {absent} -> false)
/**
Expand All @@ -542,12 +548,13 @@ 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} -> ""
errno = match error.errno with | {present=errno} -> "<errno={errno}>" | {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,assertion,assertionCode,n,errmsg]))
String.concat(" ",List.filter((s -> s != ""),[ok,err,code,errno,assertion,assertionCode,n,errmsg]))
/**
* We can't always use [bson_to_opa] to extract the error-relevant
Expand All @@ -569,6 +576,10 @@ Bson = {{
match find_int(doc,"code") with
| {some=code} -> {present=code}
| {none} -> {absent};
errno=
match find_int(doc,"errno") with
| {some=errno} -> {present=errno}
| {none} -> {absent};
assertion=
match find_string(doc, "assertion") with
| {some=assertion} -> {present=assertion}
Expand Down
35 changes: 16 additions & 19 deletions stdlib/apis/mongo/commands.opa
Original file line number Diff line number Diff line change
Expand Up @@ -500,21 +500,6 @@ MongoCommands = {{
removeShard(m:Mongo.mongodb, shard:string): Mongo.result =
simple_str_command(m, "admin", "removeShard", shard)
/* Map a list of outcomes onto an outcome of a list. */
@private
Outcome_map(f:'a->outcome('b,'c), l:list('a)): outcome(list('b),'c) =
rec aux(l) =
match l with
| [a|t] ->
(match f(a) with
| {success=b} ->
(match aux(t) with
| {success=l} -> {success=[b|l]}
| {~failure} -> {~failure})
| {~failure} -> {~failure})
| [] -> {success=[]}
aux(l)
/**
* Find a non-draining shard in a list of shards.
* You get the list of shards from the "config.shards" collection.
Expand Down Expand Up @@ -567,10 +552,10 @@ MongoCommands = {{
(match find_non_draining_shard(shards) with
| {some=shardid} ->
do println("shardid={shardid}")
res = Outcome_map((dbdoc ->
(match Bson.find_string(dbdoc,"_id") with
| {some=dbname} -> movePrimary(m, dbname, shardid)
| {none} -> {failure={Error="no db _id"}})),dbs)
res = MongoCommon.Outcome_list((dbdoc ->
(match Bson.find_string(dbdoc,"_id") with
| {some=dbname} -> movePrimary(m, dbname, shardid)
| {none} -> {failure={Error="no db _id"}})),dbs)
(match res with
| {success=_} -> aux(retryTime,retries+1)
| {~failure} -> {~failure})
Expand Down Expand Up @@ -748,6 +733,18 @@ MongoCommands = {{
(match verbose_opt with | {some=verbose} -> [H.bool("verbose",verbose)] | {none} -> [])])
run_command(m, m.dbname, cmd)
/**
* Evaluate Javascript code.
*
* Example: [eval(mongodb, dbname, code, args_opt, nolock_opt)]
**/
eval(m:Mongo.mongodb, dbname:string, code:Bson.code, args_opt:option(list(Bson.value)), nolock_opt:option(bool))
: Mongo.result =
cmd = List.flatten([[H.code("$eval",code)],
(match args_opt with | {some=args} -> [H.valarr("args",args)] | {none} -> []),
(match nolock_opt with | {some=nolock} -> [H.bool("nolock",nolock)] | {none} -> [])])
run_command(m, dbname, cmd)
@private pass_digest(user:string, pass:string): string = Crypto.Hash.md5("{user}:mongo:{pass}")
/**
Expand Down
32 changes: 32 additions & 0 deletions stdlib/apis/mongo/common.opa
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ MongoCommon = {{
| {~success} -> sfn(success)
| {~failure} -> ffn(failure)

/* Map a list of outcomes onto an outcome of a list. */
Outcome_list(f:'a->outcome('b,'c), l:list('a)): outcome(list('b),'c) =
rec aux(l) =
match l with
| [a|t] ->
(match f(a) with
| {success=b} ->
(match aux(t) with
| {success=l} -> {success=[b|l]}
| {~failure} -> {~failure})
| {~failure} -> {~failure})
| [] -> {success=[]}
aux(l)

/** Same as [outcome_map] but coerced to string **/
string_of_outcome = (outcome_map:outcome('s,'f), ('s->string), ('f->string) -> string)

Expand Down Expand Up @@ -446,6 +460,24 @@ MongoCommon = {{
| {none} -> failErr("{from}: no document in reply"))
| {none} -> failErr("{from}: no reply")

/**
* Extract all documents from a reply.
*
* Example: [reply_to_results(from, reply_opt)]
*
* @param from A string included in failure messages.
* @param reply_opt The optional reply (this is what most query operations return).
**/
reply_to_results(from:string, reply_opt: option(Mongo.reply)): Mongo.results =
match reply_opt with
| {some=reply} ->
Outcome_list((n ->
match reply_document(reply,n) with
| {some=doc} -> {success=doc}
| {none} -> failErr("{from}: no document in reply")),
List.init((n -> n),reply_numberReturned(reply)))
| {none} -> failErr("{from}: no reply")

}}

//End of file common.opa
Expand Down
64 changes: 54 additions & 10 deletions stdlib/apis/mongo/connection.opa
Original file line number Diff line number Diff line change
Expand Up @@ -149,28 +149,28 @@ MongoConnection = {{
anonymous = [];
parsers = [
{CommandLine.default_parser with
names = ["--mongo-name", "--mongoname", "-mn"]
names = ["--mongo-name", "--mongoname", "--mn", "-mn"]
description = "Name for the MongoDB server connection"
param_doc = "<string>"
on_param(p) = parser name={Rule.consume} ->
do last_name.set(name)
{no_params = add_param((p -> { p with ~name }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-repl-name", "--mongoreplname", "-mr"]
names = ["--mongo-repl-name", "--mongoreplname", "--mr", "-mr"]
description = "Replica set name for the MongoDB server"
param_doc = "<string>"
on_param(p) = parser s={Rule.consume} ->
{no_params = add_param((p -> { p with replname={some=s} }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-buf-size", "--mongobufsize", "-mb"]
names = ["--mongo-buf-size", "--mongobufsize", "--mb", "-mb"]
description = "Hint for initial MongoDB connection buffer size"
param_doc = "<int>"
on_param(p) = parser n={Rule.natural} -> {no_params = add_param((p -> { p with bufsize = n }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-concurrency", "--mongoconcurrency", "-mx"]
names = ["--mongo-concurrency", "--mongoconcurrency", "--mx", "-mx"]
description = "Concurrency type, 'pool', 'cell' or 'singlethreaded'"
param_doc = "<string>"
on_param(p) = parser s={Rule.consume} ->
Expand All @@ -183,25 +183,25 @@ MongoConnection = {{
{no_params = add_param((p -> { p with ~concurrency }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-socket-pool", "--mongosocketpool", "-mp"]
names = ["--mongo-socket-pool", "--mongosocketpool", "--mp", "-mp"]
description = "Number of sockets in socket pool (>=2 enables socket pool)"
param_doc = "<int>"
on_param(p) = parser n={Rule.natural} -> {no_params = add_param((p -> { p with pool_max = n }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-close-socket", "--mongoclosesocket", "-mc"]
names = ["--mongo-close-socket", "--mongoclosesocket", "--mc", "-mc"]
description = "Maintain MongoDB server sockets in a closed state"
param_doc = "<bool>"
on_param(p) = parser b={Rule.bool} -> {no_params = add_param((p -> { p with close_socket = b }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-log", "--mongolog", "-ml"]
names = ["--mongo-log", "--mongolog", "--ml", "-ml"]
description = "Enable MongoLog logging"
param_doc = "<bool>"
on_param(p) = parser b={Rule.bool} -> {no_params = add_param((p -> { p with log = b }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-seed", "--mongoseed", "-ms"]
names = ["--mongo-seed", "--mongoseed", "--ms", "-ms"]
description = "Add a seed to a replica set, allows multiple seeds"
param_doc = "<host>\{:<port>\}"
on_param(p) =
Expand All @@ -211,7 +211,7 @@ MongoConnection = {{
{ p with seeds=[MongoReplicaSet.mongo_host_of_string(s)|seeds] }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-host", "--mongohost", "-mh"]
names = ["--mongo-host", "--mongohost", "--mh", "-mh"]
description = "Host name of a MongoDB server, overwrites any previous addresses for this name"
param_doc = "<host>\{:<port>\}"
on_param(p) =
Expand All @@ -220,7 +220,7 @@ MongoConnection = {{
{ p with seeds=[MongoReplicaSet.mongo_host_of_string(s)] }),p)}
},
{CommandLine.default_parser with
names = ["--mongo-log-type", "--mongologtype", "-mt"]
names = ["--mongo-log-type", "--mongologtype", "--mt", "-mt"]
description = "Type of logging: stdout, stderr, logger, none"
param_doc = "<string>"
on_param(p) = parser s={Rule.consume} ->
Expand Down Expand Up @@ -504,6 +504,11 @@ MongoConnection = {{
inserte(m:Mongo.mongodb, documents:Bson.document): option(Mongo.reply) =
MongoDriver.inserte(m.mongo, m.insert_flags, "{m.dbname}.{m.collection}", m.dbname, documents)
/** Insert document with getlasterror converted into a result into the defined database with inbuilt flags **/
insert_result(m:Mongo.mongodb, documents:Bson.document): Mongo.result =
MongoCommon.reply_to_result("MongoConnection.insert_result",0,
MongoDriver.inserte(m.mongo, m.insert_flags, "{m.dbname}.{m.collection}", m.dbname, documents))
/** Insert batch of documents into the defined database with inbuilt flags **/
insert_batch(m:Mongo.mongodb, documents:list(Bson.document)): bool =
MongoDriver.insert_batch(m.mongo, m.insert_flags, "{m.dbname}.{m.collection}", documents)
Expand All @@ -512,6 +517,12 @@ MongoConnection = {{
insert_batche(m:Mongo.mongodb, documents:list(Bson.document)): option(Mongo.reply) =
MongoDriver.insert_batche(m.mongo, m.insert_flags, "{m.dbname}.{m.collection}", m.dbname, documents)
/** Insert batch of documents with getlasterror converted into a result into the defined database with inbuilt flags **/
insert_batch_result(m:Mongo.mongodb, documents:list(Bson.document)): Mongo.result =
MongoCommon.reply_to_result("MongoConnection.insert_batch_result",0,
MongoDriver.insert_batche(m.mongo, m.insert_flags, "{m.dbname}.{m.collection}",
m.dbname, documents))
/** Update document in the defined database with inbuilt flags **/
update(m:Mongo.mongodb, selector:Bson.document, update:Bson.document): bool =
MongoDriver.update(m.mongo, m.update_flags, "{m.dbname}.{m.collection}", selector, update)
Expand All @@ -520,6 +531,12 @@ MongoConnection = {{
updatee(m:Mongo.mongodb, selector:Bson.document, update:Bson.document): option(Mongo.reply) =
MongoDriver.updatee(m.mongo, m.update_flags, "{m.dbname}.{m.collection}", m.dbname, selector, update)
/** Update document with getlasterror converted into a result in the defined database with inbuilt flags **/
update_result(m:Mongo.mongodb, selector:Bson.document, update:Bson.document): Mongo.result =
MongoCommon.reply_to_result("MongoConnection.update_result",0,
MongoDriver.updatee(m.mongo, m.update_flags, "{m.dbname}.{m.collection}",
m.dbname, selector, update))
/** Perform a query using inbuilt parameters.
* The functions to handle [Mongo.reply] are in [MongoDriver].
**/
Expand All @@ -541,6 +558,11 @@ MongoConnection = {{
deletee(m:Mongo.mongodb, selector:Bson.document): option(Mongo.reply) =
MongoDriver.deletee(m.mongo, m.delete_flags, "{m.dbname}.{m.collection}", m.dbname, selector)
/** Delete documents with getlasterror converted into a result from the defined database with inbuilt flags **/
delete_result(m:Mongo.mongodb, selector:Bson.document): Mongo.result =
MongoCommon.reply_to_result("MongoConnection.delete_result",0,
MongoDriver.deletee(m.mongo, m.delete_flags, "{m.dbname}.{m.collection}", m.dbname, selector))
/** Perform a kill_cursors operation **/
kill_cursors(m:Mongo.mongodb, cursors:list(Mongo.cursorID)): bool =
MongoDriver.kill_cursors(m.mongo, cursors)
Expand All @@ -549,6 +571,11 @@ MongoConnection = {{
kill_cursorse(m:Mongo.mongodb, cursors:list(Mongo.cursorID)): option(Mongo.reply) =
MongoDriver.kill_cursorse(m.mongo, m.dbname, cursors)
/** Perform a kill_cursors operation with getlasterror converted into a result **/
kill_cursors_result(m:Mongo.mongodb, cursors:list(Mongo.cursorID)): Mongo.result =
MongoCommon.reply_to_result("MongoConnection.kill_cursors_result",0,
MongoDriver.kill_cursorse(m.mongo, m.dbname, cursors))
/** Perform a msg operation **/
msg(m:Mongo.mongodb, msg:string): bool =
MongoDriver.msg(m.mongo, msg)
Expand All @@ -557,6 +584,11 @@ MongoConnection = {{
msge(m:Mongo.mongodb, msg:string): option(Mongo.reply) =
MongoDriver.msge(m.mongo, m.dbname, msg)
/** Perform a msg operation with getlasterror converted into a result **/
msg_result(m:Mongo.mongodb, msg:string): Mongo.result =
MongoCommon.reply_to_result("MongoConnection.msg_result",0,
MongoDriver.msge(m.mongo, m.dbname, msg))
/** Add an index to the inbuilt collection **/
create_index(m:Mongo.mongodb, key:Bson.document): bool =
MongoDriver.create_index(m.mongo, "{m.dbname}.{m.collection}", key, m.index_flags)
Expand Down Expand Up @@ -606,6 +638,18 @@ MongoConnection = {{
}} // Cursor
/**
* Save a function into the system.js collection for the named database.
*
* Example: [save_function(mongodb, dbname, name, code)]
* @param mongodb The mongo connection
* @param dbname The name of the database
* @param name The name of the function
* @param code The code for the function
**/
save_function(m:Mongo.mongodb, dbname:string, name:string, code:Bson.code): Mongo.result =
insert_result(namespace(m,dbname,"system.js"),Bson.opa2doc({_id=name; value=code}))
}}
// End of file connection.opa

0 comments on commit 7c8a675

Please sign in to comment.