Index: TODO =================================================================== diff -u -rcef0608bea97458e5dcd87615c9b8ca3fe7b464c -r2fbf1bf87402e8639e772781c5719164e7e55555 --- TODO (.../TODO) (revision cef0608bea97458e5dcd87615c9b8ca3fe7b464c) +++ TODO (.../TODO) (revision 2fbf1bf87402e8639e772781c5719164e7e55555) @@ -3000,8 +3000,17 @@ * use "-withObj" in mongodb interface * adapted regression test +- mongodb interface: + * mongo::gridfile::seek: added a seek command for gridfiles + * added example for the low-level interface to shwo how + to access gridfs via the plain mongodb interface, how + to add some additional metadata (e.g. dublin core meta + data) and how to retrieve this via the gridfile interface TODO: +- extend mongo::gridfs::store_file with a switch -metadata to + pass metadata together at gridfs file creation time + - do we have to adjust the documentation in xotcl2 for object initialization? - maybe optional arg (true) to ::nsf::object::initialized to generalize -noinit Index: library/mongodb/example-nsf-gridfs.tcl =================================================================== diff -u -rdf67ed7db2b0cda881c4a9e704379a2a02d415b6 -r2fbf1bf87402e8639e772781c5719164e7e55555 --- library/mongodb/example-nsf-gridfs.tcl (.../example-nsf-gridfs.tcl) (revision df67ed7db2b0cda881c4a9e704379a2a02d415b6) +++ library/mongodb/example-nsf-gridfs.tcl (.../example-nsf-gridfs.tcl) (revision 2fbf1bf87402e8639e772781c5719164e7e55555) @@ -14,12 +14,16 @@ # $ mongo # > use myfs # > show collections +# > db.fs.files.find() # # or via the mongofiles interface: # # $ mongofiles -d myfs list # +# +# First, as usual, open the connection to the mongo db +# set mongoConn [::mongo::connect] # @@ -29,12 +33,18 @@ set gridFS [::mongo::gridfs::open $mongoConn myfs fs] # -# The current version of gridfs_store_file() is quite unfriendly, -# since it assumes that the file exists, and aborts otherwise. So, we -# perform the existance test here. +# gridfs::remove_file removes all files with the specified name +# multiple store operations create "revisions" with different uploadDates +::mongo::gridfs::remove_file $gridFS README + # +# ::mongo::gridfs::store_file $gridFS $inputFileName $storeFileName text/plain # Note that the input file name can be "-" for reading from stdin. # +# The current version of gridfs_store_file() is quite unfriendly, +# since it assumes that the file exists, and aborts otherwise. So, we +# perform the existence test here. +# # Store a known file: # set fn README @@ -45,29 +55,63 @@ puts stderr "no such file: $fn" } -# unknown file -set fn unknown-file -if {[file readable $fn]} { - set r [::mongo::gridfs::store_file $gridFS $fn $fn text/plain] - puts stderr r=$r -} else { - puts stderr "no such file: $fn" -} - +# +# Open a grid file, get some of its properties, and read it in chunks +# of 500 bytes, and close it finally. +# set f [mongo::gridfile::open $gridFS README] -puts stderr "opened file $f" -puts stderr meta=[mongo::gridfile::get_metadata $f] -puts stderr contentlength=[mongo::gridfile::get_contentlength $f] -puts stderr contenttype=[mongo::gridfile::get_contenttype $f] +puts stderr "\nOpened grid file $f" +puts stderr "Metadata: [mongo::gridfile::get_metadata $f]" +puts stderr "ContentLength: [mongo::gridfile::get_contentlength $f]" +puts stderr "ContentType: [mongo::gridfile::get_contenttype $f]" while {1} { set chunk [mongo::gridfile::read $f 500] puts stderr "read chunk-len [string length $chunk] content [string range $chunk 0 10]..." - if {[string length $chunk] < 500} break; + if {[string length $chunk] < 500} { + break + } } mongo::gridfile::close $f -puts stderr OK # +# Access the files stored in the gridfs via plain query interface +# +puts "\nAll Files:\n[join [::mongo::query $mongoConn myfs.fs.files {}] \n]\n" + +# +# Get the file named README from the gridfs via plain query interface +# +set atts [lindex [::mongo::query $mongoConn myfs.fs.files \ + [list \$query object {filename string README}] \ + -limit 1] 0] +puts "Attributes of file README:\n$atts\n" + +# +# Extract the oid from the bson attributes +# +foreach {name type value} $atts { + if {$name eq "_id"} { + set oid $value + break + } +} + +# +# Add a dc:creator to the bson attributes ... +# +lappend atts metadata object {dc:creator string "Gustaf Neumann"} +# .. and update the entry in the gridfs +::mongo::update $mongoConn myfs.fs.files [list _id oid $oid] $atts + +# +# Now we can use the gridfs interface to obtain the additional +# metadata as well +# +set f [mongo::gridfile::open $gridFS README] +puts stderr "Metadata: [mongo::gridfile::get_metadata $f]" +mongo::gridfile::close $f + +# # close everything # ::mongo::gridfs::close $gridFS Index: library/mongodb/mongoAPI.decls =================================================================== diff -u -rcef0608bea97458e5dcd87615c9b8ca3fe7b464c -r2fbf1bf87402e8639e772781c5719164e7e55555 --- library/mongodb/mongoAPI.decls (.../mongoAPI.decls) (revision cef0608bea97458e5dcd87615c9b8ca3fe7b464c) +++ library/mongodb/mongoAPI.decls (.../mongoAPI.decls) (revision 2fbf1bf87402e8639e772781c5719164e7e55555) @@ -95,24 +95,28 @@ # GridFile # -cmd gridfile::close NsfMongoGridFileClose { +cmd "gridfile::close" NsfMongoGridFileClose { {-argName "file" -required 1 -type gridfile -withObj 1} } -cmd gridfile::get_contentlength NsfMongoGridFileGetContentlength { +cmd "gridfile::get_contentlength" NsfMongoGridFileGetContentlength { {-argName "file" -required 1 -type gridfile} } -cmd gridfile::get_contenttype NsfMongoGridFileGetContentType { +cmd "gridfile::get_contenttype" NsfMongoGridFileGetContentType { {-argName "file" -required 1 -type gridfile} } -cmd gridfile::get_metadata NsfMongoGridFileGetMetaData { +cmd "gridfile::get_metadata" NsfMongoGridFileGetMetaData { {-argName "file" -required 1 -type gridfile} } -cmd gridfile::open NsfMongoGridFileOpen { +cmd "gridfile::open" NsfMongoGridFileOpen { {-argName "fs" -required 1 -type gridfs} {-argName "filename" -required 1} } -cmd gridfile::read NsfMongoGridFileRead { +cmd "gridfile::read" NsfMongoGridFileRead { {-argName "file" -required 1 -type gridfile} {-argName "size" -required 1 -type int32} } +cmd "gridfile::seek" NsfMongoGridFileSeek { + {-argName "file" -required 1 -type gridfile} + {-argName "offset" -required 1 -type int32} +} \ No newline at end of file Index: library/mongodb/mongoAPI.h =================================================================== diff -u -rcef0608bea97458e5dcd87615c9b8ca3fe7b464c -r2fbf1bf87402e8639e772781c5719164e7e55555 --- library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision cef0608bea97458e5dcd87615c9b8ca3fe7b464c) +++ library/mongodb/mongoAPI.h (.../mongoAPI.h) (revision 2fbf1bf87402e8639e772781c5719164e7e55555) @@ -19,6 +19,7 @@ static int NsfMongoGridFileGetMetaDataStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfMongoGridFileOpenStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfMongoGridFileReadStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfMongoGridFileSeekStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfMongoIndexStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfMongoInsertStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfMongoQueryStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -38,6 +39,7 @@ static int NsfMongoGridFileGetMetaData(Tcl_Interp *interp, gridfile *filePtr); static int NsfMongoGridFileOpen(Tcl_Interp *interp, gridfs *fsPtr, CONST char *filename); static int NsfMongoGridFileRead(Tcl_Interp *interp, gridfile *filePtr, int size); +static int NsfMongoGridFileSeek(Tcl_Interp *interp, gridfile *filePtr, int size); static int NsfMongoIndex(Tcl_Interp *interp, mongo_connection *connPtr, CONST char *namespace, Tcl_Obj *attributes, int withDropdups, int withUnique); static int NsfMongoInsert(Tcl_Interp *interp, mongo_connection *connPtr, CONST char *namespace, Tcl_Obj *values); static int NsfMongoQuery(Tcl_Interp *interp, mongo_connection *connPtr, CONST char *namespace, Tcl_Obj *query, Tcl_Obj *withAtts, int withLimit, int withSkip); @@ -58,6 +60,7 @@ NsfMongoGridFileGetMetaDataIdx, NsfMongoGridFileOpenIdx, NsfMongoGridFileReadIdx, + NsfMongoGridFileSeekIdx, NsfMongoIndexIdx, NsfMongoInsertIdx, NsfMongoQueryIdx, @@ -325,6 +328,26 @@ } static int +NsfMongoGridFileSeekStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + ParseContext pc; + (void)clientData; + + if (ArgumentParse(interp, objc, objv, NULL, objv[0], + method_definitions[NsfMongoGridFileSeekIdx].paramDefs, + method_definitions[NsfMongoGridFileSeekIdx].nrParameters, 1, + &pc) != TCL_OK) { + return TCL_ERROR; + } else { + gridfile *filePtr = (gridfile *)pc.clientData[0]; + int size = (int )PTR2INT(pc.clientData[1]); + + assert(pc.status == 0); + return NsfMongoGridFileSeek(interp, filePtr, size); + + } +} + +static int NsfMongoIndexStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ParseContext pc; (void)clientData; @@ -488,6 +511,10 @@ {"file", NSF_ARG_REQUIRED, 1, Nsf_ConvertToPointer, NULL,NULL,"gridfile",NULL,NULL,NULL,NULL,NULL}, {"size", NSF_ARG_REQUIRED, 1, Nsf_ConvertToInt32, NULL,NULL,"int32",NULL,NULL,NULL,NULL,NULL}} }, +{"::mongo::gridfile::seek", NsfMongoGridFileSeekStub, 2, { + {"file", NSF_ARG_REQUIRED, 1, Nsf_ConvertToPointer, NULL,NULL,"gridfile",NULL,NULL,NULL,NULL,NULL}, + {"size", NSF_ARG_REQUIRED, 1, Nsf_ConvertToInt32, NULL,NULL,"int32",NULL,NULL,NULL,NULL,NULL}} +}, {"::mongo::index", NsfMongoIndexStub, 5, { {"conn", NSF_ARG_REQUIRED, 1, Nsf_ConvertToPointer, NULL,NULL,"mongo_connection",NULL,NULL,NULL,NULL,NULL}, {"namespace", NSF_ARG_REQUIRED, 1, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, Index: library/mongodb/nsfmongo.c =================================================================== diff -u -rcef0608bea97458e5dcd87615c9b8ca3fe7b464c -r2fbf1bf87402e8639e772781c5719164e7e55555 --- library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision cef0608bea97458e5dcd87615c9b8ca3fe7b464c) +++ library/mongodb/nsfmongo.c (.../nsfmongo.c) (revision 2fbf1bf87402e8639e772781c5719164e7e55555) @@ -887,6 +887,9 @@ /*********************************************************************** * GridFile interface + * + * Currently offsets and sizes are limited to 32bit integers, we should + * relax this later. ***********************************************************************/ /* @@ -993,6 +996,22 @@ return TCL_OK; } +/* +cmd "gridfile::seek" NsfMongoGridFileSeek { + {-argName "file" -required 1 -type gridfile} + {-argName "offset" -required 1 -type int32} +} +*/ +static int +NsfMongoGridFileSeek(Tcl_Interp *interp, gridfile *gridFilePtr, int offset) { + int pos; + + pos = gridfile_seek(gridFilePtr, offset); + Tcl_SetObjResult(interp, Tcl_NewIntObj(pos)); + + return TCL_OK; +} + /*********************************************************************** * Finally, provide the necessary Tcl package interface. ***********************************************************************/