Index: TODO =================================================================== diff -u -r7495af656ca04a32826ecb0b6e207f886eaaa7f8 -r2b56284a45054d5136ddfb67343a70655aba5666 --- TODO (.../TODO) (revision 7495af656ca04a32826ecb0b6e207f886eaaa7f8) +++ TODO (.../TODO) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -4068,9 +4068,22 @@ - updated 34 copyright notices +nsf.c: +- extended nsf::method::delete to handle ensemble names + +nx.tcl: +- added tk/incr-tcl style cget methods on class/object levels. +- improve copy handling with other child-types of the slot container working +- make sure to ignore non-slot-type objects in slot introspection +- worked on regression test until "methods.test". others are missing, + but maybe reconsideration + ======================================================================== TODO: -- handling of method names in nsfAPI.h. The following +- maybe revise class/object level cgets by implementing a global method + +- check for potential simplications in scripts for nsf::method::delete +- handling of method names in error messages from nsfAPI.h. The following ? {o __alloc x} {method __alloc not dispatched on valid class} should be ? {o __alloc x} {method alloc not dispatched on valid class} Index: generic/nsf.c =================================================================== diff -u -r7495af656ca04a32826ecb0b6e207f886eaaa7f8 -r2b56284a45054d5136ddfb67343a70655aba5666 --- generic/nsf.c (.../nsf.c) (revision 7495af656ca04a32826ecb0b6e207f886eaaa7f8) +++ generic/nsf.c (.../nsf.c) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -941,12 +941,14 @@ NsfDeleteObject(Tcl_Interp *interp, Nsf_Object *object) { return DispatchDestroyMethod(interp, (NsfObject *)object, 0); } + EXTERN int NsfRemoveObjectMethod(Tcl_Interp *interp, Nsf_Object *object1, CONST char *methodName) { NsfObject *object = (NsfObject *) object1; - NsfObjectMethodEpochIncr("NsfRemoveObjectMethod"); + /*fprintf(stderr, "... NsfRemoveObjectMethod %s %s\n", ObjectName(object), methodName);*/ + NsfObjectMethodEpochIncr("NsfRemoveObjectMethod"); AliasDelete(interp, object->cmdName, methodName, 1); #if defined(NSF_WITH_ASSERTIONS) @@ -964,16 +966,17 @@ } return TCL_OK; } + EXTERN int NsfRemoveClassMethod(Tcl_Interp *interp, Nsf_Class *class, CONST char *methodName) { NsfClass *cl = (NsfClass *) class; int rc; #if defined(NSF_WITH_ASSERTIONS) NsfClassOpt *opt = cl->opt; #endif + /*fprintf(stderr, "... NsfRemoveClassMethod %s %s\n", ClassName(class), methodName);*/ NsfInstanceMethodEpochIncr("NsfRemoveClassMethod"); - AliasDelete(interp, class->object.cmdName, methodName, 0); #if defined(NSF_WITH_ASSERTIONS) @@ -12518,7 +12521,6 @@ * Both, args and body are empty strings. This means we should delete the * method. */ - if (RUNTIME_STATE(interp)->exitHandlerDestroyRound == NSF_EXITHANDLER_OFF) { /* * Don't delete methods via scripting during shutdown @@ -13381,7 +13383,8 @@ Tcl_DString ds, *dsPtr = &ds; int fullQualPattern = (pattern && *pattern == ':'); - /*fprintf(stderr, "AddSlotObjects parent %s prefix %s\n", ObjectName(parent), prefix);*/ + /*fprintf(stderr, "AddSlotObjects parent %s prefix %s type %p %s\n", + ObjectName(parent), prefix, type, type ? ClassName(type) : "");*/ DSTRING_INIT(dsPtr); Tcl_DStringAppend(dsPtr, ObjectName(parent), -1); @@ -19414,9 +19417,45 @@ static int NsfMethodDeleteCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, Tcl_Obj *methodNameObj) { - return NsfMethodCreateCmd(interp, object, 0, withPer_object, NULL, methodNameObj, - NsfGlobalObjs[NSF_EMPTY], NsfGlobalObjs[NSF_EMPTY], - NULL, NULL); + + NsfObject *regObject, *defObject; + CONST char *methodName1 = NULL; + NsfClass *cl = withPer_object == 0 && NsfObjectIsClass(object) ? (NsfClass *)object : NULL; + int fromClassNS = cl != NULL, result; + Tcl_DString ds, *dsPtr = &ds; + Tcl_Command cmd; + + Tcl_DStringInit(dsPtr); + + cmd = ResolveMethodName(interp, cl ? cl->nsPtr : object->nsPtr, methodNameObj, + dsPtr, ®Object, &defObject, &methodName1, &fromClassNS); + + /*fprintf(stderr, + "NsfMethodDeleteCmd method %s '%s' object %p regObject %p defObject %p cl %p fromClass %d cmd %p\n", + ObjStr(methodNameObj), methodName1, object, regObject, defObject, cl, fromClassNS, cmd);*/ + + if (cmd) { + methodName1 = Tcl_GetCommandName(interp, cmd); + if (defObject) { + cl = withPer_object == 0 && NsfObjectIsClass(defObject) ? (NsfClass *)defObject : NULL; + } else { + defObject = object; + } + + result = cl ? + NsfRemoveClassMethod(interp, (Nsf_Class *)defObject, methodName1) : + NsfRemoveObjectMethod(interp, (Nsf_Object *)defObject, methodName1); + + } else { + result = NsfPrintError(interp, "%s: %s method '%s' does not exist", + ObjectName(object), + withPer_object ? "object specific" : "instance", + ObjStr(methodNameObj)); + } + + Tcl_DStringFree(dsPtr); + + return result; } /* Index: library/mongodb/README =================================================================== diff -u -rebba70b7b0b296de45cb263fa850913ac8711a27 -r2b56284a45054d5136ddfb67343a70655aba5666 --- library/mongodb/README (.../README) (revision ebba70b7b0b296de45cb263fa850913ac8711a27) +++ library/mongodb/README (.../README) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -9,7 +9,8 @@ Compile or obtain the mongo-c-driver (client interface) Assume, Tcl is under /usr/local/ns/lib and the mongo-c-driver is under -/usr/local/src/mongo-c-driver/, then configre the nsf interface via +/usr/local/src/mongo-c-driver/, then configure the nsf interface via the +following command from nsf*/library/mongodb/ ./configure --with-tcl=/usr/local/ns/lib --with-nsf=../../ \ --with-mongo=/usr/local/src/mongo-c-driver/src/,/usr/local/src/mongo-c-driver Index: library/mongodb/example-nsf-mongo.tcl =================================================================== diff -u -r9248d253eb37bcefbfa38a1d86df306f40922444 -r2b56284a45054d5136ddfb67343a70655aba5666 --- library/mongodb/example-nsf-mongo.tcl (.../example-nsf-mongo.tcl) (revision 9248d253eb37bcefbfa38a1d86df306f40922444) +++ library/mongodb/example-nsf-mongo.tcl (.../example-nsf-mongo.tcl) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -15,9 +15,12 @@ if {1} { ::mongo::remove $mongoConn tutorial.persons {} - puts stderr "\nInserting a few tuples" - ::mongo::insert $mongoConn tutorial.persons [list name string Joe projects string abc age int 23 \ - classes array {0 object {$ref string courses $id oid 1}}] + puts "\nInserting a few tuples" + if {[catch { + ::mongo::insert $mongoConn tutorial.persons [list name string Joe projects string abc age int 23 \ + classes array {0 object {$ref string courses $id oid 1}}] + }]} {puts "!!! cannot insert dbref;\ + most likely, the c-driver does not support yet insertion of \$ref, \$id and \$db fields"} ::mongo::insert $mongoConn tutorial.persons [list name string Gustaf projects string nsf age int 53] ::mongo::insert $mongoConn tutorial.persons [list name string Stefan projects string nsf] ::mongo::insert $mongoConn tutorial.persons [list name string Franz info object {x int 203 y int 102} age int 29 projects string gtat] Index: library/mongodb/mongoAPI.h =================================================================== diff -u -rc9ef41c49f482a38e89f7cffc54cabf909710425 -r2b56284a45054d5136ddfb67343a70655aba5666 --- library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision c9ef41c49f482a38e89f7cffc54cabf909710425) +++ library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -1,7 +1,27 @@ +/* + * This source code file was generated by the C-code generator gentclAPI.tcl, + * part of the Next Scripting Framework. + */ +#if !defined(likely) +# if defined(__GNUC__) && __GNUC__ > 2 +/* Use gcc branch prediction hint to minimize cost of e.g. DTrace + * ENABLED checks. + */ +# define unlikely(x) (__builtin_expect((x), 0)) +# define likely(x) (__builtin_expect((x), 1)) +# else +# define unlikely(x) (x) +# define likely(x) (x) +# endif +#endif + + + + /* just to define the symbol */ -static Nsf_methodDefinition method_definitions[]; +static Nsf_methodDefinition method_definitions[20]; static CONST char *method_command_namespace_names[] = { "::mongo" @@ -74,17 +94,17 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoCloseIdx].paramDefs, method_definitions[NsfMongoCloseIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; assert(pc.status == 0); return NsfMongoClose(interp, connPtr,pc.objv[0]); + } else { + return TCL_ERROR; } } @@ -93,19 +113,19 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoConnectIdx].paramDefs, method_definitions[NsfMongoConnectIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { CONST char *withReplica_set = (CONST char *)pc.clientData[0]; Tcl_Obj *withServer = (Tcl_Obj *)pc.clientData[1]; int withTimeout = (int )PTR2INT(pc.clientData[2]); assert(pc.status == 0); return NsfMongoConnect(interp, withReplica_set, withServer, withTimeout); + } else { + return TCL_ERROR; } } @@ -114,19 +134,19 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoCountIdx].paramDefs, method_definitions[NsfMongoCountIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; CONST char *namespace = (CONST char *)pc.clientData[1]; Tcl_Obj *query = (Tcl_Obj *)pc.clientData[2]; assert(pc.status == 0); return NsfMongoCount(interp, connPtr, namespace, query); + } else { + return TCL_ERROR; } } @@ -135,17 +155,17 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFSCloseIdx].paramDefs, method_definitions[NsfMongoGridFSCloseIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfs *gfsPtr = (gridfs *)pc.clientData[0]; assert(pc.status == 0); return NsfMongoGridFSClose(interp, gfsPtr,pc.objv[0]); + } else { + return TCL_ERROR; } } @@ -154,19 +174,19 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFSOpenIdx].paramDefs, method_definitions[NsfMongoGridFSOpenIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; CONST char *dbname = (CONST char *)pc.clientData[1]; CONST char *prefix = (CONST char *)pc.clientData[2]; assert(pc.status == 0); return NsfMongoGridFSOpen(interp, connPtr, dbname, prefix); + } else { + return TCL_ERROR; } } @@ -175,18 +195,18 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFSRemoveFileIdx].paramDefs, method_definitions[NsfMongoGridFSRemoveFileIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfs *gfsPtr = (gridfs *)pc.clientData[0]; CONST char *filename = (CONST char *)pc.clientData[1]; assert(pc.status == 0); return NsfMongoGridFSRemoveFile(interp, gfsPtr, filename); + } else { + return TCL_ERROR; } } @@ -195,12 +215,10 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFSStoreFileIdx].paramDefs, method_definitions[NsfMongoGridFSStoreFileIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfs *gfsPtr = (gridfs *)pc.clientData[0]; CONST char *filename = (CONST char *)pc.clientData[1]; CONST char *remotename = (CONST char *)pc.clientData[2]; @@ -209,6 +227,8 @@ assert(pc.status == 0); return NsfMongoGridFSStoreFile(interp, gfsPtr, filename, remotename, contenttype); + } else { + return TCL_ERROR; } } @@ -217,17 +237,17 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFileCloseIdx].paramDefs, method_definitions[NsfMongoGridFileCloseIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfile *filePtr = (gridfile *)pc.clientData[0]; assert(pc.status == 0); return NsfMongoGridFileClose(interp, filePtr,pc.objv[0]); + } else { + return TCL_ERROR; } } @@ -236,17 +256,17 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFileGetContentTypeIdx].paramDefs, method_definitions[NsfMongoGridFileGetContentTypeIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfile *filePtr = (gridfile *)pc.clientData[0]; assert(pc.status == 0); return NsfMongoGridFileGetContentType(interp, filePtr); + } else { + return TCL_ERROR; } } @@ -255,17 +275,17 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFileGetContentlengthIdx].paramDefs, method_definitions[NsfMongoGridFileGetContentlengthIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfile *filePtr = (gridfile *)pc.clientData[0]; assert(pc.status == 0); return NsfMongoGridFileGetContentlength(interp, filePtr); + } else { + return TCL_ERROR; } } @@ -274,17 +294,17 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFileGetMetaDataIdx].paramDefs, method_definitions[NsfMongoGridFileGetMetaDataIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfile *filePtr = (gridfile *)pc.clientData[0]; assert(pc.status == 0); return NsfMongoGridFileGetMetaData(interp, filePtr); + } else { + return TCL_ERROR; } } @@ -293,18 +313,18 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFileOpenIdx].paramDefs, method_definitions[NsfMongoGridFileOpenIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfs *fsPtr = (gridfs *)pc.clientData[0]; CONST char *filename = (CONST char *)pc.clientData[1]; assert(pc.status == 0); return NsfMongoGridFileOpen(interp, fsPtr, filename); + } else { + return TCL_ERROR; } } @@ -313,18 +333,18 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFileReadIdx].paramDefs, method_definitions[NsfMongoGridFileReadIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfile *filePtr = (gridfile *)pc.clientData[0]; int size = (int )PTR2INT(pc.clientData[1]); assert(pc.status == 0); return NsfMongoGridFileRead(interp, filePtr, size); + } else { + return TCL_ERROR; } } @@ -333,18 +353,18 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoGridFileSeekIdx].paramDefs, method_definitions[NsfMongoGridFileSeekIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { gridfile *filePtr = (gridfile *)pc.clientData[0]; int offset = (int )PTR2INT(pc.clientData[1]); assert(pc.status == 0); return NsfMongoGridFileSeek(interp, filePtr, offset); + } else { + return TCL_ERROR; } } @@ -353,12 +373,10 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoIndexIdx].paramDefs, method_definitions[NsfMongoIndexIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; CONST char *namespace = (CONST char *)pc.clientData[1]; Tcl_Obj *attributes = (Tcl_Obj *)pc.clientData[2]; @@ -370,6 +388,8 @@ assert(pc.status == 0); return NsfMongoIndex(interp, connPtr, namespace, attributes, withBackground, withDropdups, withSparse, withUnique); + } else { + return TCL_ERROR; } } @@ -378,19 +398,19 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoInsertIdx].paramDefs, method_definitions[NsfMongoInsertIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; CONST char *namespace = (CONST char *)pc.clientData[1]; Tcl_Obj *values = (Tcl_Obj *)pc.clientData[2]; assert(pc.status == 0); return NsfMongoInsert(interp, connPtr, namespace, values); + } else { + return TCL_ERROR; } } @@ -399,12 +419,10 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoQueryIdx].paramDefs, method_definitions[NsfMongoQueryIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; CONST char *namespace = (CONST char *)pc.clientData[1]; Tcl_Obj *query = (Tcl_Obj *)pc.clientData[2]; @@ -415,6 +433,8 @@ assert(pc.status == 0); return NsfMongoQuery(interp, connPtr, namespace, query, withAtts, withLimit, withSkip); + } else { + return TCL_ERROR; } } @@ -423,19 +443,19 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoRemoveIdx].paramDefs, method_definitions[NsfMongoRemoveIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; CONST char *namespace = (CONST char *)pc.clientData[1]; Tcl_Obj *condition = (Tcl_Obj *)pc.clientData[2]; assert(pc.status == 0); return NsfMongoRemove(interp, connPtr, namespace, condition); + } else { + return TCL_ERROR; } } @@ -444,12 +464,10 @@ ParseContext pc; (void)clientData; - if (ArgumentParse(interp, objc, objv, NULL, objv[0], + if (likely(ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMongoUpdateIdx].paramDefs, method_definitions[NsfMongoUpdateIdx].nrParameters, 0, 1, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { + &pc) == TCL_OK)) { mongo *connPtr = (mongo *)pc.clientData[0]; CONST char *namespace = (CONST char *)pc.clientData[1]; Tcl_Obj *cond = (Tcl_Obj *)pc.clientData[2]; @@ -460,10 +478,12 @@ assert(pc.status == 0); return NsfMongoUpdate(interp, connPtr, namespace, cond, values, withUpsert, withAll); + } else { + return TCL_ERROR; } } -static Nsf_methodDefinition method_definitions[] = { +static Nsf_methodDefinition method_definitions[20] = { {"::mongo::close", NsfMongoCloseStub, 1, { {"conn", NSF_ARG_REQUIRED, 1, Nsf_ConvertToPointer, NULL,NULL,"mongo",NULL,NULL,NULL,NULL,NULL}} }, Index: library/mongodb/nsfmongo.c =================================================================== diff -u -rc9ef41c49f482a38e89f7cffc54cabf909710425 -r2b56284a45054d5136ddfb67343a70655aba5666 --- library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision c9ef41c49f482a38e89f7cffc54cabf909710425) +++ library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -643,7 +643,8 @@ } bson_finish(b); - result = mongo_insert(connPtr, namespace, b); + /* for the time being, no write_concern (last arg of mongo_insert()) */ + result = mongo_insert(connPtr, namespace, b, NULL); if (result == MONGO_ERROR) { result = NsfPrintError(interp, ErrorMsg(connPtr->err)); @@ -735,7 +736,8 @@ } BsonAppendObjv(interp, query, objc, objv); - mongo_remove(connPtr, namespace, query); + /* for the time being, no write_concern (last arg of mongo_remove()) */ + mongo_remove(connPtr, namespace, query, NULL); bson_destroy(query); return TCL_OK; @@ -775,7 +777,9 @@ if (withUpsert) {options |= 1;} if (withAll) {options |= 2;} - mongo_update(connPtr, namespace, cond, values, options); + + /* for the time being, no write_concern (last arg of mongo_update()) */ + mongo_update(connPtr, namespace, cond, values, options, NULL); return TCL_OK; } @@ -919,7 +923,7 @@ NsfMongoGridFileGetMetaData(Tcl_Interp *interp, gridfile* gridFilePtr) { bson b; - b = gridfile_get_metadata(gridFilePtr); + gridfile_get_metadata(gridFilePtr, &b); Tcl_SetObjResult(interp, BsonToList(interp, b.data, 0)); return TCL_OK; Index: library/nx/nx.tcl =================================================================== diff -u -r7495af656ca04a32826ecb0b6e207f886eaaa7f8 -r2b56284a45054d5136ddfb67343a70655aba5666 --- library/nx/nx.tcl (.../nx.tcl) (revision 7495af656ca04a32826ecb0b6e207f886eaaa7f8) +++ library/nx/nx.tcl (.../nx.tcl) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -158,7 +158,6 @@ set ensembleName ${object}::$w } #puts stderr "NX check $scope $object info methods $path @ <$w> cmd=[info command $w] obj?[nsf::object::exists $ensembleName] " - #if {[::nsf::directdispatch $object ::nsf::methods::${scope}::info::methods $w] eq ""} if {![nsf::object::exists $ensembleName]} { # # Create dispatch/ensemble object and accessor method (if wanted) @@ -182,9 +181,16 @@ set type [::nsf::directdispatch $object ::nsf::methods::${scope}::info::method type $w] set definition [::nsf::directdispatch $object ::nsf::methods::${scope}::info::method definition $w] if {$scope eq "class"} { - if {$type ne "alias"} {error "can't append to $type"} - if {$definition eq ""} {error "definition must not be empty"} - set object [lindex $definition end] + if {$type eq ""} { + # In case of a copy operation, the ensemble object might + # exist, but the alias might be missing. + ::nsf::method::alias $object $w $ensembleName + set object $ensembleName + } else { + if {$type ne "alias"} {error "can't append to $type"} + if {$definition eq ""} {error "definition must not be empty"} + set object [lindex $definition end] + } } else { if {$type ne "object"} {error "can't append to $type"} if {[llength $definition] != 3} {error "unexpected definition '$definition'"} @@ -273,7 +279,13 @@ ###################################################################### # Well, class is not a method defining method either, but a modifier - array set ::nsf::methodDefiningMethod {method 1 alias 1 property 1 forward 1 class 1} + array set ::nsf::methodDefiningMethod { + method 1 alias 1 property 1 forward 1 class 1 + ::nsf::classes::nx::Class::method 1 ::nsf::classes::nx::Object::method 1 + ::nsf::classes::nx::Class::alias 1 ::nsf::classes::nx::Object::alias 1 + ::nsf::classes::nx::Class::property 1 ::nsf::classes::nx::Object::property 1 + ::nsf::classes::nx::Class::forward 1 ::nsf::classes::nx::Object::forward 1 + } ###################################################################### # Provide method modifiers for ::nx::Object @@ -523,7 +535,7 @@ # Object public method "delete property" {name} { # call explicitly the per-object variant of "info::slotobjects" - set slot [: ::nsf::methods::object::info::slotobjects $name] + set slot [: ::nsf::methods::object::info::slotobjects -type ::nx::Slot $name] if {$slot eq ""} {error "[self]: cannot delete object specific property '$name'"} $slot destroy nsf::var::unset -nocomplain [self] $name @@ -537,7 +549,7 @@ error "[self]: object does not have an instance variable '$name'" } # call explicitly the per-object variant of "info::slotobejcts" - set slot [: ::nsf::methods::object::info::slotobjects $name] + set slot [: ::nsf::methods::object::info::slotobjects -type ::nx::Slot $name] if {$slot ne ""} { # it is not a slot-less variable @@ -660,20 +672,20 @@ :alias "info precedence" ::nsf::methods::object::info::precedence :method "info slot definition" {{-type:class ::nx::Slot} pattern:optional} { set result {} - foreach slot [: ::nsf::methods::object::info::slotobjects {*}[current args]] { + foreach slot [: ::nsf::methods::object::info::slotobjects -type $type {*}[current args]] { lappend result [$slot getPropertyDefinition] } return $result } :method "info slot names" {{-type:class ::nx::Slot} pattern:optional} { set result {} - foreach slot [: ::nsf::methods::object::info::slotobjects {*}[current args]] { + foreach slot [: ::nsf::methods::object::info::slotobjects -type $type {*}[current args]] { lappend result [$slot name] } return $result } :method "info slot objects" {{-type:class ::nx::Slot} pattern:optional} { - return [: ::nsf::methods::object::info::slotobjects {*}[current args]] + return [: ::nsf::methods::object::info::slotobjects -type $type {*}[current args]] } # "info properties" is a short form of "info slot definition" :alias "info properties" ::nx::Object::slot::__info::slot::definition @@ -754,7 +766,7 @@ } :method "info slot definition" {{-type ::nx::Slot} -closure:switch -source:optional pattern:optional} { set result {} - foreach slot [: ::nsf::methods::class::info::slotobjects {*}[current args]] { + foreach slot [: ::nsf::methods::class::info::slotobjects -type $type {*}[current args]] { lappend result [$slot getPropertyDefinition] } return $result @@ -1161,16 +1173,31 @@ if {[::nsf::is class ${:domain}]} { ::nsf::invalidateobjectparameter ${:domain} } + #puts stderr "*** slot destroy of [self], domain ${:domain} per-object ${:per-object}" # - # delete the accessor + # delete the accessors # + set cgetName "cget -${:name}" if {${:per-object}} { if {[${:domain} ::nsf::methods::object::info::method exists ${:name}]} { ::nsf::method::delete ${:domain} -per-object ${:name} } - } elseif {[${:domain} ::nsf::methods::class::info::method exists ${:name}]} { - ::nsf::method::delete ${:domain} ${:name} + if {[${:domain} ::nsf::methods::object::info::method exists ${cgetName}]} { + nsf::method::delete ${:domain} -per-object ${cgetName} + # TODO cleanup + #puts stderr "nsf::method::delete ${:domain} -per-object ${cgetName}" + #puts stderr o-still=[${:domain} ::nsf::methods::object::info::method exists ${cgetName}] + } + } else { + #array set "" [${:domain} eval [list :__resolve_method_path $cgetName]] + if {[${:domain} ::nsf::methods::class::info::method exists ${:name}]} { + ::nsf::method::delete ${:domain} ${:name} + } + if {[${:domain} ::nsf::methods::class::info::method exists ${cgetName}]} { + nsf::method::delete ${:domain} ${cgetName} + #puts stderr c-still=[${:domain} ::nsf::methods::class::info::method exists ${cgetName}] + } } } ::nsf::next @@ -1644,12 +1671,23 @@ } ::nx::VariableSlot public method makeAccessor {} { + set needsForwarder [:needsForwarder] + if {$needsForwarder} { + set body "{[self]} get \[self\] ${:name}" + } else { + set body "return \${:${:name}}" + } + ${:domain} public \ + [expr {${:per-object} ? "::nsf::classes::nx::Object::method" : "::nsf::classes::nx::Class::method"}] \ + "cget -${:name}" \ + {} $body + if {!${:accessor}} { #puts stderr "Do not register forwarder ${:domain} ${:name}" return 0 } - if {[:needsForwarder]} { + if {$needsForwarder} { set handle [:makeForwarder] :makeIncrementalOperations } else { @@ -2210,16 +2248,18 @@ # get class specific slots # if {[::nsf::is class $origin]} { - set slots [$origin ::nsf::methods::class::info::slotobjects] + set slots [$origin ::nsf::methods::class::info::slotobjects -type ::nx::Slot] } # # append object specific slots # - foreach slot [$origin ::nsf::methods::object::info::slotobjects] { + foreach slot [$origin ::nsf::methods::object::info::slotobjects -type ::nx::Slot] { lappend slots $slot } - #puts stderr "replacing domain and manager from <$origin> to <$dest> in slots <$slots>" + puts stderr "replacing domain and manager from <$origin> to <$dest> in slots <$slots>" foreach oldslot $slots { + puts stderr "check slot <$oldslot> class [nsf::relation $oldslot class] s?[$oldslot info has type ::nx::Slot]" + #if {![$oldslot info has type ::nx::Slot]} continue set container [expr {[$oldslot per-object] ? "per-object-slot" : "slot"}] set newslot [::nx::slotObj -container $container $dest [namespace tail $oldslot]] if {[$oldslot domain] eq $origin} {$newslot domain $dest} Index: tests/methods.test =================================================================== diff -u -ra5dfcb547e25f83286793ba9850b988b822adf3e -r2b56284a45054d5136ddfb67343a70655aba5666 --- tests/methods.test (.../methods.test) (revision a5dfcb547e25f83286793ba9850b988b822adf3e) +++ tests/methods.test (.../methods.test) (revision 2b56284a45054d5136ddfb67343a70655aba5666) @@ -170,9 +170,9 @@ ? {::nsf::dispatch c1 protected_object_alias} "protected_object_alias" ? {lsort [c1 info methods]} \ - "plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter" + "cget plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter" ? {lsort [C class info methods]} \ - "plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter s3" + "cget plain_object_alias plain_object_forward plain_object_method plain_object_setter public_object_alias public_object_forward public_object_method public_object_setter s3" } C destroy @@ -336,8 +336,8 @@ } ? {C x 1} 1 ? {C x} 1 - ? {C info methods} "a" - ? {C class info methods} x + ? {lsort [C info methods]} "a cget" + ? {lsort [C class info methods]} "cget x" ? {c1 a b} {expected integer but got "b" for parameter "a"} set s(C) [C serialize] @@ -358,8 +358,8 @@ # tests should work as again ? {C x} 1 - ? {C info methods} "a" - ? {C class info methods} x + ? {lsort [C info methods]} "a cget" + ? {lsort [C class info methods]} "cget x" ? {c1 a b} {expected integer but got "b" for parameter "a"} } @@ -375,13 +375,13 @@ :create c1 } - ? {::nsf::method::delete C x} "::C: cannot delete method 'x'" - ? {::nsf::method::delete C -per-object x} "::C: cannot delete object specific method 'x'" + ? {::nsf::method::delete C x} "::C: instance method 'x' does not exist" + ? {::nsf::method::delete C -per-object x} "::C: object specific method 'x' does not exist" ? {::nsf::method::delete C foo} "" - ? {::nsf::method::delete C foo} "::C: cannot delete method 'foo'" - ? {::nsf::method::delete C bar} "::C: cannot delete method 'bar'" + ? {::nsf::method::delete C foo} "::C: instance method 'foo' does not exist" + ? {::nsf::method::delete C bar} "::C: instance method 'bar' does not exist" ? {::nsf::method::delete C -per-object bar} "" - ? {::nsf::method::delete C -per-object bar} "::C: cannot delete object specific method 'bar'" + ? {::nsf::method::delete C -per-object bar} "::C: object specific method 'bar' does not exist" } # @@ -543,10 +543,10 @@ :public method "info bar foo" {} {return [namespace current]-[namespace which info]} } - ? {o1 info methods -path} "{info foo} {info bar foo} foo a1 a2" - ? {o1 info children} "::o1::info ::o1::per-object-slot" + ? {o1 info methods -path} "{info foo} {info bar foo} foo a1 a2 {cget -a2} {cget -a1}" + ? {o1 info children} "::o1::info ::o1::per-object-slot ::o1::cget" - ? {o1 delete method bar} "::o1: cannot delete object specific method 'bar'" + ? {o1 delete method bar} "::o1: object specific method 'bar' does not exist" # For a1, we have a method and an property. We can delete the # method without the slot. ? {o1 delete method a1} "" @@ -559,7 +559,7 @@ # try to delete the property again: ? {o1 delete property a1} "::o1: cannot delete object specific property 'a1'" - ? {o1 info methods -path} "{info foo} {info bar foo} foo a2" + ? {o1 info methods -path} "{info foo} {info bar foo} foo a2 {cget -a2}" ? {o1 delete property a2} "" ? {o1 info methods -path} "{info foo} {info bar foo} foo" @@ -589,10 +589,10 @@ :property a2 } - ? {C class info methods -path} "{info foo} {info bar foo} foo a1" - ? {C info children} "::C::info ::C::slot ::C::per-object-slot" + ? {C class info methods -path} "{info foo} {info bar foo} foo a1 {cget -a1}" + ? {C info children} "::C::info ::C::slot ::C::per-object-slot ::C::cget" - ? {C class delete method bar} "::C: cannot delete object specific method 'bar'" + ? {C class delete method bar} "::C: object specific method 'bar' does not exist" ? {C class delete property a1} "" ? {C class info methods -path} "{info foo} {info bar foo} foo" @@ -607,7 +607,7 @@ ? {C class delete method "info bar foo"} "" ? {C class info methods -path} "" - ? {C info methods} "a2" + ? {C info methods} "a2 cget" ? {C info slot objects} "::C::slot::a2" } @@ -627,10 +627,10 @@ :public method "info bar foo" {} {return [namespace current]-[namespace which info]} } - ? {C info methods -path} "{info foo} {info bar foo} foo a1" + ? {C info methods -path} "{info foo} {info bar foo} foo a1 {cget -a1}" ? {C info children} "::C::slot" - ? {C delete method bar} "::C: cannot delete method 'bar'" + ? {C delete method bar} "::C: instance method 'bar' does not exist" ? {C delete property a1} "" ? {C info methods -path} "{info foo} {info bar foo} foo"