Index: TODO =================================================================== diff -u -r417968f9109f1c27af478b142b34b64f38e3908e -ra5bf2874a6cb0338860062dce1846279c1704444 --- TODO (.../TODO) (revision 417968f9109f1c27af478b142b34b64f38e3908e) +++ TODO (.../TODO) (revision a5bf2874a6cb0338860062dce1846279c1704444) @@ -2890,6 +2890,13 @@ - added value checker type int32 (similar to "string is integer") and changed value checker "integer" to accept all integers +- library/mongodb: + * use type int32 + * updated to new nx/nsf interfaces + * updated for mongo-c-driver post 0.3 + (supporting result MONGO_OK for mongo_cursor_next) + * factored out "mongo cond" from "mongo query" + TODO: Index: library/mongodb/example-nx-mongo.tcl =================================================================== diff -u -r9248d253eb37bcefbfa38a1d86df306f40922444 -ra5bf2874a6cb0338860062dce1846279c1704444 --- library/mongodb/example-nx-mongo.tcl (.../example-nx-mongo.tcl) (revision 9248d253eb37bcefbfa38a1d86df306f40922444) +++ library/mongodb/example-nx-mongo.tcl (.../example-nx-mongo.tcl) (revision a5bf2874a6cb0338860062dce1846279c1704444) @@ -40,6 +40,16 @@ Person insert -name Franz -projects {gtat annobackend abc} -age 29 # +# Quick check of the results: count all persons and count the persons +# named Gustaf +# +set count [Person count] +puts "We have $count Persons in the database" + +set count [Person count -cond {name = Gustaf}] +puts "We have $count Persons named Gustaf" + +# # Lookup a single Person, create an instance of the object ... # set p [Person find first -cond {name = Gustaf}] Index: library/mongodb/mongoAPI.decls =================================================================== diff -u -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e -ra5bf2874a6cb0338860062dce1846279c1704444 --- library/mongodb/mongoAPI.decls (.../mongoAPI.decls) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) +++ library/mongodb/mongoAPI.decls (.../mongoAPI.decls) (revision a5bf2874a6cb0338860062dce1846279c1704444) @@ -42,8 +42,8 @@ {-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} + {-argName "-limit" -required 0 -nrargs 1 -type int32} + {-argName "-skip" -required 0 -nrargs 1 -type int32} } cmd remove NsfMongoRemove { Index: library/mongodb/mongoAPI.h =================================================================== diff -u -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e -ra5bf2874a6cb0338860062dce1846279c1704444 --- library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) +++ library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision a5bf2874a6cb0338860062dce1846279c1704444) @@ -213,49 +213,49 @@ static Nsf_methodDefinition method_definitions[] = { {"::mongo::close", NsfMongoCloseStub, 1, { - {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} + {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::mongo::connect", NsfMongoConnectStub, 2, { - {"-replica-set", 0, 1, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, - {"-server", 0, 1, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} + {"-replica-set", 0, 1, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-server", 0, 1, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::mongo::count", NsfMongoCountStub, 3, { - {"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}} + {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"query", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::mongo::index", NsfMongoIndexStub, 5, { - {"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}, - {"attributes", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, - {"-dropdups", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, - {"-unique", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} + {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"attributes", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-dropdups", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-unique", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::mongo::insert", NsfMongoInsertStub, 3, { - {"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}, - {"values", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} + {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"values", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::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}} + {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"query", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-atts", 0, 1, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-limit", 0, 1, Nsf_ConvertToInt32, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-skip", 0, 1, Nsf_ConvertToInt32, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::mongo::remove", NsfMongoRemoveStub, 3, { - {"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}, - {"condition", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} + {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"condition", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::mongo::update", NsfMongoUpdateStub, 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}, - {"cond", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, - {"values", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, - {"-upsert", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, - {"-all", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} + {"conn", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"namespace", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"cond", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"values", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-upsert", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-all", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} },{NULL} }; Index: library/mongodb/nsfmongo.c =================================================================== diff -u -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e -ra5bf2874a6cb0338860062dce1846279c1704444 --- library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) +++ library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision a5bf2874a6cb0338860062dce1846279c1704444) @@ -172,7 +172,7 @@ if ( t == 0 ) break; key = bson_iterator_key( &i ); - /*fprintf(stderr, "key %s t %d string %d\n", key, t, bson_string);*/ + /*fprintf(stderr, "BsonToList: key %s t %d string %d\n", key, t, bson_string);*/ switch ( t ){ case bson_int: tag = "integer"; elemObj = Tcl_NewIntObj(bson_iterator_int( &i )); break; @@ -206,7 +206,7 @@ default: tag = "unknown"; elemObj = Tcl_NewStringObj("", 0); - fprintf( stderr , "unknown type : %d\n" , t ); + fprintf( stderr , "BsonToList: unknown type %d\n" , t ); } Tcl_ListObjAppendElement(interp, resultObj, Tcl_NewStringObj(key, -1)); @@ -257,7 +257,7 @@ case 't': /* timestamp */ return bson_timestamp; } - NsfLog(interp, NSF_LOG_WARN, "Treat unknown tag '%s' as string", tag); + NsfLog(interp, NSF_LOG_WARN, "BsonTagToType: Treat unknown tag '%s' as string", tag); return bson_string; } @@ -281,7 +281,7 @@ int result = TCL_OK; bson_type t = BsonTagToType(interp, tag); - /*fprintf(stderr, "add name %s tag %s value '%s'\n", name, tag, ObjStr(value));*/ + /*fprintf(stderr, "BsonAppend: add name %s tag %s value '%s'\n", name, tag, ObjStr(value));*/ switch ( t ){ case bson_string: @@ -359,16 +359,16 @@ int i, objc; Tcl_Obj **objv; - bson_buffer *(*bsonStartFn)( bson_buffer *b, const char *name); - bsonStartFn = (t == bson_object) ? bson_append_start_object : bson_append_start_array; - result = Tcl_ListObjGetElements(interp, value, &objc, &objv); if (result != TCL_OK || objc % 3 != 0) { return NsfPrintError(interp, "invalid %s value contain multiple of 3 elements %s", tag, ObjStr(value)); } - (*bsonStartFn)( bbPtr, name); - + if (t == bson_object) { + bson_append_start_object(bbPtr, name); + } else { + bson_append_start_array(bbPtr, name); + } for (i = 0; i< objc; i += 3) { /*fprintf(stderr, "value %s, i %d, [0]: %s, [1]: %s, [2]: %s\n", ObjStr(value), i, ObjStr(objv[i]), ObjStr(objv[i+1]), ObjStr(objv[i+2]));*/ @@ -466,7 +466,6 @@ buffer[offset] = '\0'; host = buffer; port = atoi(buffer+offset+1); - fprintf(stderr, "port=%d\n", port); } else { /* * The passed string contained no colon. @@ -748,8 +747,8 @@ {-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} + {-argName "-limit" -required 0 -type int32} + {-argName "-skip" -required 0 -type int32} } */ static int @@ -763,6 +762,9 @@ bson query[1]; bson atts[1]; + /*fprintf(stderr, "NsfMongoQuery: namespace %s withLimit %d withSkip %d\n", + namespace, withLimit, withSkip);*/ + if (connPtr == NULL) { return NsfObjErrType(interp, "", connObj, "connection", NULL); } @@ -780,6 +782,7 @@ objc2 = 0; } + /* fprintf(stderr, "query # %d, atts # %d\n", objc1, objc2); */ BsonAppendObjv(interp, query, objc1, objv1); BsonAppendObjv(interp, atts, objc2, objv2); @@ -790,7 +793,7 @@ * http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol#MongoWireProtocol-OPQUERY */ cursor = mongo_find( connPtr, namespace, query, atts, withLimit, withSkip, 0 ); - while( mongo_cursor_next( cursor ) ) { + while( mongo_cursor_next( cursor ) == MONGO_OK ) { Tcl_ListObjAppendElement(interp, resultObj, BsonToList(interp, (&cursor->current)->data, 0)); } Index: library/mongodb/nx-mongo.tcl =================================================================== diff -u -r9248d253eb37bcefbfa38a1d86df306f40922444 -ra5bf2874a6cb0338860062dce1846279c1704444 --- library/mongodb/nx-mongo.tcl (.../nx-mongo.tcl) (revision 9248d253eb37bcefbfa38a1d86df306f40922444) +++ library/mongodb/nx-mongo.tcl (.../nx-mongo.tcl) (revision a5bf2874a6cb0338860062dce1846279c1704444) @@ -220,7 +220,7 @@ :method "get slot" {att} { set classes [concat [self] [:info mixin classes] [:info heritage]] foreach cls $classes { - set slot [$cls info slot $att] + set slot [$cls info slots $att] if {$slot ne ""} { return $slot } @@ -234,28 +234,38 @@ # # For interaction with bson structures, we provide on the class - # level "bson query" (a small dsl for a more convenient syntax in - # bson queries), "bson atts (a simplifed attribute selection) and + # level "bson cond" (a small dsl for a more convenient syntax in + # bson queries), "bson query" (combining conditions with + # ordering), "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 ""}} { + + :method "bson cond" {cond} { + #puts "bson cond $cond" set bson [list] foreach {att op value} $cond { set slot [:get slot $att] - switch $op { - "=" {lappend bson $att [$slot mongotype] $value} - ">" - "<" - "<=" - ">=" - "!=" { - lappend bson $att object [list [:get relop $op] [$slot mongotype] $value] + switch $op { + "=" {lappend bson $att [$slot mongotype] $value} + ">" - "<" - "<=" - ">=" - "!=" { + lappend bson $att object [list [:get relop $op] [$slot mongotype] $value] + } + "in" - "all" { + lappend bson $att object [list [:get relop $op] {*}[$slot bson encode -array $value]] + } + default {error "unknown operator $op"} } - "in" - "all" { - lappend bson $att object [list [:get relop $op] {*}[$slot bson encode -array $value]] - } - default {error "unknown operator $op"} } - } + #puts "bson cond <$cond> => $bson" + return $bson + } + + :method "bson query" {{-cond ""} {-orderby ""}} { + #puts "bson query -cond <$cond> -orderby <$orderby>" + set bson [:bson cond $cond] set result [list \$query object $bson] + if {[llength $orderby] > 0} { set bson [list] foreach attspec $orderby { @@ -264,7 +274,7 @@ } lappend result \$orderby object $bson } - #puts "Query: $result" + #puts "bson query -cond <$cond> -orderby <$orderby> => $result" return $result } @@ -280,13 +290,14 @@ } :method "bson parameter" {tuple} { - #puts "bson parameter $tuple" + #puts "bson parameter: <$tuple>" set objParams [list] foreach {att type value} $tuple { set slot [:get slot $att] #puts stderr "att $att type $type value $value => '$slot'" lappend objParams -$att [$slot bson decode $type $value] } + #puts "bson parameter <$tuple> => $objParams" return $objParams } @@ -359,7 +370,7 @@ # number of tuples for the query. # :public method count {{-cond ""}} { - return [::nx::mongo::db count ${:mongo_ns} $cond] + return [::nx::mongo::db count ${:mongo_ns} [:bson cond $cond]] } #