# -*- tcl -*- # # This is an example how to use the nx mongo mapping. We show here # single class mapped to the mongo db with sing and multivalued # scalars together with some querying options. # # Gustaf Neumann fecit, April 2011 # package require nx::mongo package require nx::test #nsf::configure debug 2 # Establish connection to the database ? {::nx::mongo::db connect -db "tutorial"} mongoc_client_t:0 # # Create or lookup collection handle; the first operation is a create, # the second a lookup. # ? {::nx::mongo::db collection tutorial.persons} "mongoc_collection_t:0" ? {::nx::mongo::db collection tutorial.persons} "mongoc_collection_t:0" # # When we create a capped collection, we cannot use # # nx::mongo::db delete tutorial.persons {} # # but have to use "drop collection" to get rid of it (this is enforced # by MongoDB 2.6.3 or newer). nx::mongo::db drop collection persons # # Create the application class "Person" # ? { nx::mongo::Class create Person { :index name :property name:required :property projects:0..n {set :incremental 1} :property age:integer } } ::Person # # Insert a tuple to the database via creating an object, saving and # destroying it: # ? { nsf::is object [set p [Person new -name Gustaf -projects {nsf nx nxmongo} -age 53]]} 1 ? { nx::mongo::db is_oid [$p save]} 1 ? { $p destroy; nsf::is object $p} 0 # # The insert operation of above can be achieved with less typing via # the convenience method "insert": # ? { nx::mongo::db is_oid [Person insert -name Stefan -projects {nsf nx}]} 1 ? { nx::mongo::db is_oid [Person insert -name Joe -projects abc -age 23]} 1 ? { nx::mongo::db is_oid [Person insert -name Franz -projects {gtat annobackend abc} -age 29]} 1 # # Quick check of the results: count all persons and count the persons # named Gustaf # ? {Person count} 4 ? {Person count -cond {name = Gustaf}} 1 set n "Gustaf" ? {Person count -cond [list name = $n]} 1 # # Lookup a single Person, create an instance of the object ... # ? {nsf::is object [set p [Person find first -cond {name = Gustaf}]]} 1 ? {Person find first -cond {name = unknown-name}} "" #puts [$p serialize] # # ... change the age, add an project, and save it. # ? {$p configure -age 55} "" ? {$p projects add xowiki} "xowiki nsf nx nxmongo" ? {nx::mongo::db is_oid [$p save]} 1 ? {$p destroy; nsf::is object $p} 0 # # Lookup a single Person and create a named object # ? {Person find first -instance p2 -cond {name = Gustaf}} ::p2 ? {lsort [p2 info vars]} "_id age name projects" ? {p2 destroy; nsf::is object p2} 0 # # Test a few queries based on the user-friendly query language defined # for the class objects. # puts "\nProject members of nsf:" ? {llength [set persons [Person find all -cond {projects = nsf}]]} 2 ? {lsort [lmap p $persons {$p cget -name}]} "Gustaf Stefan" puts "\nProject members of nsf or gtat:" ? {llength [set persons [Person find all -cond {projects in {nsf gtat}} -orderby name]]} 3 ? {lsort [lmap p $persons {$p cget -name}]} "Franz Gustaf Stefan" puts "\nProject members working on both nsf and nxmongo:" ? {llength [set persons [Person find all -cond {projects all {nsf nxmongo}}]]} 1 ? {lsort [lmap p $persons {$p cget -name}]} "Gustaf" puts "\nAll Persons sorted by name (ascending):" ? {llength [set persons [Person find all -orderby name]]} 4 ? {lmap p $persons {$p cget -name}} "Franz Gustaf Joe Stefan" puts "\nMembers of Projects != 'abc' nsf sorted by name desc and age:" ? {llength [set persons [Person find all -cond {projects != "abc"} -orderby {{name desc} age}]]} 2 ? {lmap p $persons {$p cget -name}} "Stefan Gustaf" puts "\nFind persons age > 30:" ? {llength [set persons [Person find all -cond {age > 30}]]} 1 ? {lsort [lmap p $persons {$p cget -name}]} "Gustaf" puts "\nFind persons with names matching regular expression /an/i (containing 'an', ignore case):" ? {llength [set persons [Person find all -cond {name ~ {an i}}]]} 2 ? {lsort [lmap p $persons {$p cget -name}]} "Franz Stefan" # # Define a special find method for "Person" named "oldies" by # extending the query interface (add sub-method to ensemble). # Person public object method "find oldies" {} { return [:find all -cond {age > 30}] } # # Use the special find method # puts "\nFind oldies:" ? {llength [set persons [Person find oldies]]} 1 ? {lsort [lmap p $persons {$p cget -name}]} "Gustaf" puts "\nCreate user with default for password:" ? { #nsf::__profile_trace -enable true -dontsave true -verbose 1 nx::mongo::Class create User { :index name :property name:required :property -incremental {groups:0..n ""} :property {password ""} } } ::User #nsf::__profile_trace -enable false ::User create u1 -name GN -groups {admin teacher} ? {u1 bson asJSON} {{ "__class" : "::User", "groups" : [ "admin", "teacher" ], "name" : "GN", "password" : "" }} # check autoclosing nx::mongo::db close # # Local variables: # mode: tcl # tcl-indent-level: 2 # indent-tabs-mode: nil # End: