- Legacy Driver Implementation Documentation >
- MongoDB Driver Requirements
MongoDB Driver Requirements¶
This legacy documentation does not necessarily reflect the current practices in MongoDB driver implementation, but may be useful for historical purposes. See the MongoDB Meta Driver for the current documentation of MongoDB driver implementation.
This is a high-level list of features that a driver for MongoDB might provide. We attempt to group those features by priority. This list should be taken with a grain of salt, and probably used more for inspiration than as law that must be adhered to. A great way to learn about implementing a driver is by reading the source code of any of the existing drivers, especially the ones listed as “mongodb.org supported”.
- BSON serialization/deserialization
- full cursor support (e.g. support OP_GET_MORE operation)
- close exhausted cursors via OP_KILL_CURSORS
- support for running database commands
- handle query errors
- convert all strings to UTF-8 (part of proper support for BSON)
- hint(), explain(), count(), $where
- database profiling: set/get profiling level, get profiling info
- advanced connection management (replica sets, slaveOkay)
- automatic reconnection
- validate a collection in a database
- buffer pooling
- Tailable cursor support
A driver should be able to connect to a single server. By default this must be localhost:27017, and must also allow the server to be specified by hostname and port.
Mongo m = new Mongo(); // go to localhost, default port Mongo m = new Mongo(String host, int port);
How the driver does this is up to the driver - make it idiomatic. However, a driver should make it explicit and clear what is going on.
A driver must be able to support “Replica-Set” configurations, where multiple mongod servers are specified, and configured for hot-failover.
The driver should determine which of the nodes is the current master, and send all operations to that server. In the event of an error, either socket error or a “not a master” error, the driver must restart the determination process.
Cluster Mode Connect to master in master-slave cluster
ServerCluster sc = new ServerCluster(INETAddr...); // again, give one and discover? Mongo m = new Mongo(sc);
## Connect to slave in read-only mode in master-slave cluster
ServerCluster sc = new ServerCluster(INETAddr...); // again, give one and discover? sc.setTarget(...) Mongo m = new Mongo(sc); or maybe make it like *Default/Simple* w/ a flag?
Other than that, we need a way to get a DB object:
Mongo m = new Mongo(); DB db = m.getDB(name);
And a list of db names (useful for tools...) :
Simple operations on a database object :
/** * get name of database */ String dbName = db.getName(); /** * Get a list of all the collection names in this database */ List<String> cols = db.getCollectionNames(); /** * get a collection object. Can optionally create it if it * doesn't exist, or just be strict. (XJDM has strictness as an option) */ Collection coll = db.getCollection(string); /** * Create a collection w/ optional options. Can fault * if the collection exists, or can just return it if it already does */ Collection coll = db.createCollection( string); Collection coll = db.createCollection( string, options); /** * Drop a collection by its name or by collection object. * Driver could invalidate any outstanding Collection objects * for that collection, or just hope for the best. */ boolean b = db.dropCollection(name); boolean b = db.dropCollection(Collection); /** * Execute a command on the database, returning the * BSON doc with the results */ Document d = db.executeCommand(command); /** * Close the [logical] database */ void db.close(); /** * Erase / drop an entire database */ bool dropDatabase(dbname)
These methods have to do with database metadata: profiling levels and collection validation. Each admin object is associated with a database. These methods could either be built into the Database class or provided in a separate Admin class whose instances are only available from a database instance.
/* get an admin object from a database object. */ Admin admin = db.getAdmin(); /** * Get profiling level. Returns one of the strings "off", "slowOnly", or * "all". Note that the database returns an integer. This method could * return an int or an enum instead --- in Ruby, for example, we return * symbols. */ String profilingLevel = admin.getProfilingLevel(); /** * Set profiling level. Takes whatever getProfilingLevel() returns. */ admin.setProfilingLevel("off"); /** * Retrieves the database's profiling info. */ Document profilingInfo = admin.getProfilingInfo(); /** * Returns true if collection is valid; raises an exception if not. */ boolean admin.validateCollection(collectionName);
/** * full query capabilities - limit, skip, returned fields, sort, etc */ Cursor find(...); void insert(...) // insert one or more objects into the collection, local variants on args void remove(query) // remove objects that match the query void update(selector, modifier) // modify all objects that match selector w/ modifier object void updateFirst(selector, object) // replace first object that match selector w/ specified object void upsert(selector, object) // replace first object that matches, or insert long getCount(); long getCount(query);
void createIndex( index_info) void dropIndex(name) void dropIndexes() List<info> getIndexInformation()
document explain(query) options getOptions(); string getName(); void close();
document getNextDocument() iterator getIterator() // again, local to language bool hasMore() void close()