Index: TODO =================================================================== diff -u -r247831dfafdb972eaf34feca38b7b67ce38c9155 -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e --- TODO (.../TODO) (revision 247831dfafdb972eaf34feca38b7b67ce38c9155) +++ TODO (.../TODO) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) @@ -2640,6 +2640,8 @@ - nsfmongo.c: * upgrade to newest c-driver (verison 0.3) from git. * support connection to replica sets + * support attribute selection lists for ::mongo::query + (positive and negative selection) TODO: Index: library/mongodb/example-nsf-mongo.tcl =================================================================== diff -u -r247831dfafdb972eaf34feca38b7b67ce38c9155 -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e --- library/mongodb/example-nsf-mongo.tcl (.../example-nsf-mongo.tcl) (revision 247831dfafdb972eaf34feca38b7b67ce38c9155) +++ library/mongodb/example-nsf-mongo.tcl (.../example-nsf-mongo.tcl) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) @@ -34,9 +34,13 @@ puts stderr "\nProject members of nsf sorted by name" puts [join [::mongo::query $mongoConn tutorial.persons [list \$query object {projects string nsf} \$orderby object {name int 1}]] \n] -puts stderr "\nAge > 30" +puts stderr "\nAge > 30 (all atts)" puts [join [::mongo::query $mongoConn tutorial.persons [list \$query object {age object {$gt int 30}}]] \n] +puts stderr "\nAge > 30 (only atts name and age)" +puts [join [::mongo::query $mongoConn tutorial.persons [list \$query object {age object {$gt int 30}}] \ + -atts {name int 1 age int 1}] \n] + puts stderr "\nCount Age > 30" puts [::mongo::count $mongoConn tutorial.persons {age object {$gt int 30}}] Index: library/mongodb/mongoAPI.decls =================================================================== diff -u -r247831dfafdb972eaf34feca38b7b67ce38c9155 -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e --- library/mongodb/mongoAPI.decls (.../mongoAPI.decls) (revision 247831dfafdb972eaf34feca38b7b67ce38c9155) +++ library/mongodb/mongoAPI.decls (.../mongoAPI.decls) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) @@ -41,6 +41,7 @@ {-argName "conn" -required 1 -type tclobj} {-argName "namespace" -required 1} {-argName "query" -required 1 -type tclobj} + {-argName "-atts" -required 0 -nrargs 1 -type tclobj} {-argName "-limit" -required 0 -nrargs 1 -type int} {-argName "-skip" -required 0 -nrargs 1 -type int} } Index: library/mongodb/mongoAPI.h =================================================================== diff -u -r247831dfafdb972eaf34feca38b7b67ce38c9155 -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e --- library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision 247831dfafdb972eaf34feca38b7b67ce38c9155) +++ library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) @@ -25,7 +25,7 @@ static int NsfMongoCount(Tcl_Interp *interp, Tcl_Obj *conn, CONST char *namespace, Tcl_Obj *query); static int NsfMongoIndex(Tcl_Interp *interp, Tcl_Obj *conn, CONST char *namespace, Tcl_Obj *attributes, int withDropdups, int withUnique); static int NsfMongoInsert(Tcl_Interp *interp, Tcl_Obj *conn, CONST char *namespace, Tcl_Obj *values); -static int NsfMongoQuery(Tcl_Interp *interp, Tcl_Obj *conn, CONST char *namespace, Tcl_Obj *query, int withLimit, int withSkip); +static int NsfMongoQuery(Tcl_Interp *interp, Tcl_Obj *conn, CONST char *namespace, Tcl_Obj *query, Tcl_Obj *withAtts, int withLimit, int withSkip); static int NsfMongoRemove(Tcl_Interp *interp, Tcl_Obj *conn, CONST char *namespace, Tcl_Obj *condition); static int NsfMongoUpdate(Tcl_Interp *interp, Tcl_Obj *conn, CONST char *namespace, Tcl_Obj *cond, Tcl_Obj *values, int withUpsert, int withAll); @@ -156,11 +156,12 @@ Tcl_Obj *conn = (Tcl_Obj *)pc.clientData[0]; CONST char *namespace = (CONST char *)pc.clientData[1]; Tcl_Obj *query = (Tcl_Obj *)pc.clientData[2]; - int withLimit = (int )PTR2INT(pc.clientData[3]); - int withSkip = (int )PTR2INT(pc.clientData[4]); + Tcl_Obj *withAtts = (Tcl_Obj *)pc.clientData[3]; + int withLimit = (int )PTR2INT(pc.clientData[4]); + int withSkip = (int )PTR2INT(pc.clientData[5]); assert(pc.status == 0); - return NsfMongoQuery(interp, conn, namespace, query, withLimit, withSkip); + return NsfMongoQuery(interp, conn, namespace, query, withAtts, withLimit, withSkip); } } @@ -235,10 +236,11 @@ {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"values", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, -{"::mongo::query", NsfMongoQueryStub, 5, { +{"::mongo::query", NsfMongoQueryStub, 6, { {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"query", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-atts", 0, 1, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-limit", 0, 1, Nsf_ConvertToInteger, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-skip", 0, 1, Nsf_ConvertToInteger, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, Index: library/mongodb/nsfmongo.c =================================================================== diff -u -r247831dfafdb972eaf34feca38b7b67ce38c9155 -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e --- library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision 247831dfafdb972eaf34feca38b7b67ce38c9155) +++ library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) @@ -747,45 +747,56 @@ {-argName "conn" -required 1 -type tclobj} {-argName "namespace" -required 1} {-argName "query" -required 1 -type tclobj} + {-argName "-atts" -required 0 -nrargs 1 -type tclobj} {-argName "-limit" -required 0 -type int} {-argName "-skip" -required 0 -type int} } */ static int -NsfMongoQuery(Tcl_Interp *interp, Tcl_Obj *connObj, CONST char *namespace, Tcl_Obj *queryObj, +NsfMongoQuery(Tcl_Interp *interp, Tcl_Obj *connObj, CONST char *namespace, + Tcl_Obj *queryObj, Tcl_Obj *withAttsObj, int withLimit, int withSkip) { - int objc, result; - Tcl_Obj **objv, *resultObj; + int objc1, objc2, result; + Tcl_Obj **objv1, **objv2, *resultObj; mongo_connection *connPtr = MongoGetConn(connObj); mongo_cursor *cursor; bson query[1]; - bson empty[1]; + bson atts[1]; if (connPtr == NULL) { return NsfObjErrType(interp, "", connObj, "connection", NULL); } - result = Tcl_ListObjGetElements(interp, queryObj, &objc, &objv); - if (result != TCL_OK || (objc % 3 != 0)) { + result = Tcl_ListObjGetElements(interp, queryObj, &objc1, &objv1); + if (result != TCL_OK || (objc1 % 3 != 0)) { return NsfPrintError(interp, "%s: must contain a multiple of 3 elements", ObjStr(queryObj)); } + if (withAttsObj) { + result = Tcl_ListObjGetElements(interp, withAttsObj, &objc2, &objv2); + if (result != TCL_OK || (objc2 % 3 != 0)) { + return NsfPrintError(interp, "%s: must contain a multiple of 3 elements", ObjStr(withAttsObj)); + } + } else { + objc2 = 0; + } - BsonAppendObjv(interp, query, objc, objv); - bson_empty( empty ); + BsonAppendObjv(interp, query, objc1, objv1); + BsonAppendObjv(interp, atts, objc2, objv2); + resultObj = Tcl_NewListObj(0, NULL); /* * The last field of mongo_find is options, semantics are described here * http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol#MongoWireProtocol-OPQUERY */ - cursor = mongo_find( connPtr, namespace, query, NULL, withLimit, withSkip, 0 ); + cursor = mongo_find( connPtr, namespace, query, atts, withLimit, withSkip, 0 ); while( mongo_cursor_next( cursor ) ) { Tcl_ListObjAppendElement(interp, resultObj, BsonToList(interp, (&cursor->current)->data, 0)); } mongo_cursor_destroy( cursor ); bson_destroy( query ); - bson_destroy( empty ); + bson_destroy( atts ); Tcl_SetObjResult(interp, resultObj); Index: library/mongodb/nx-mongo.tcl =================================================================== diff -u -reef878fdd83b2fcf27a2644e6e8788a12f714c26 -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e --- library/mongodb/nx-mongo.tcl (.../nx-mongo.tcl) (revision eef878fdd83b2fcf27a2644e6e8788a12f714c26) +++ library/mongodb/nx-mongo.tcl (.../nx-mongo.tcl) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) @@ -231,9 +231,9 @@ # # For interaction with bson structures, we provide on the class # level "bson query" (a small dsl for a more convenient syntax in - # bson queries) and "bson parameter" which translates from a bson - # structure (tuple) into a dashed parameter list used in object - # creation. + # bson queries), "bson atts (a simplifed attribute selection) and + # "bson parameter" which translates from a bson structure (tuple) + # into a dashed parameter list used in object creation. # :method "bson query" {{-cond ""} {-orderby ""}} { @@ -260,7 +260,18 @@ #puts "Query: $result" return $result } - + + :method "bson atts" {atts} { + set result {} + foreach {att value} $atts { + if {![string is integer -strict $value]} { + error "$atts: $value should be integer" + } + lappend result $att int $value + } + return $result + } + :method "bson parameter" {tuple} { #puts "bson parameter $tuple" set objParams [list] @@ -350,18 +361,21 @@ # :public method "find first" { {-instance ""} + {-atts ""} {-cond ""} {-orderby ""} } { set tuple [lindex [::nx::mongo::db query ${:mongo_ns} \ [:bson query -cond $cond -orderby $orderby] \ + -atts [:bson atts $atts] \ -limit 1] 0] #puts "find first fetched: $tuple" if {$instance ne ""} {set instance [:uplevel [list ::nsf::object::qualify $instance]]} return [:bson create -name $instance $tuple] } :public method "find all" { + {-atts ""} {-cond ""} {-orderby ""} {-limit} @@ -373,6 +387,7 @@ if {[info exists skip]} {lappend opts -skip $skip} set fetched [::nx::mongo::db query ${:mongo_ns} \ [:bson query -cond $cond -orderby $orderby] \ + -atts [:bson atts $atts] \ {*}$opts] puts "[join $fetched \n]" foreach tuple $fetched { @@ -382,6 +397,7 @@ } :public method show { + {-atts ""} {-cond ""} {-orderby ""} {-limit} @@ -393,6 +409,7 @@ if {[info exists skip]} {lappend opts -skip $skip} set fetched [::nx::mongo::db query ${:mongo_ns} \ [:bson query -cond $cond -orderby $orderby] \ + -atts [:bson atts $atts] \ {*}$opts] set tuples [list] foreach tuple $fetched {